Reset vtid after fork in child
[lttng-ust.git] / libust / lttng-ust-abi.c
1 /*
2 * lttng-ust-abi.c
3 *
4 * Copyright 2010-2011 (c) - Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
5 *
6 * LTTng UST ABI
7 *
8 * Mimic system calls for:
9 * - session creation, returns an object descriptor or failure.
10 * - channel creation, returns an object descriptor or failure.
11 * - Operates on a session object descriptor
12 * - Takes all channel options as parameters.
13 * - stream get, returns an object descriptor or failure.
14 * - Operates on a channel object descriptor.
15 * - stream notifier get, returns an object descriptor or failure.
16 * - Operates on a channel object descriptor.
17 * - event creation, returns an object descriptor or failure.
18 * - Operates on a channel object descriptor
19 * - Takes an event name as parameter
20 * - Takes an instrumentation source as parameter
21 * - e.g. tracepoints, dynamic_probes...
22 * - Takes instrumentation source specific arguments.
23 *
24 * Dual LGPL v2.1/GPL v2 license.
25 */
26
27 #include <ust/lttng-ust-abi.h>
28 #include <urcu/compiler.h>
29 #include <urcu/list.h>
30 #include <ust/lttng-events.h>
31 #include <ust/usterr-signal-safe.h>
32 #include "ust/core.h"
33 #include "ltt-tracer.h"
34
35 /*
36 * Object descriptor table. Should be protected from concurrent access
37 * by the caller.
38 */
39
40 struct obj {
41 union {
42 struct {
43 void *private_data;
44 const struct objd_ops *ops;
45 int f_count;
46 } s;
47 int freelist_next; /* offset freelist. end is -1. */
48 } u;
49 };
50
51 struct objd_table {
52 struct obj *array;
53 unsigned int len, allocated_len;
54 int freelist_head; /* offset freelist head. end is -1 */
55 };
56
57 static struct objd_table objd_table = {
58 .freelist_head = -1,
59 };
60
61 static
62 int objd_alloc(void *private_data, const struct objd_ops *ops)
63 {
64 struct obj *obj;
65
66 if (objd_table.freelist_head != -1) {
67 obj = &objd_table.array[objd_table.freelist_head];
68 objd_table.freelist_head = obj->u.freelist_next;
69 goto end;
70 }
71
72 if (objd_table.len >= objd_table.allocated_len) {
73 unsigned int new_allocated_len, old_allocated_len;
74 struct obj *new_table, *old_table;
75
76 old_allocated_len = objd_table.allocated_len;
77 old_table = objd_table.array;
78 if (!old_allocated_len)
79 new_allocated_len = 1;
80 else
81 new_allocated_len = old_allocated_len << 1;
82 new_table = zmalloc(sizeof(struct obj) * new_allocated_len);
83 if (!new_table)
84 return -ENOMEM;
85 memcpy(new_table, old_table,
86 sizeof(struct obj) * old_allocated_len);
87 free(old_table);
88 objd_table.array = new_table;
89 objd_table.allocated_len = new_allocated_len;
90 }
91 obj = &objd_table.array[objd_table.len];
92 objd_table.len++;
93 end:
94 obj->u.s.private_data = private_data;
95 obj->u.s.ops = ops;
96 obj->u.s.f_count = 2; /* count == 1 : object is allocated */
97 /* count == 2 : allocated + hold ref */
98 return obj - objd_table.array;
99 }
100
101 static
102 struct obj *_objd_get(int id)
103 {
104 if (id >= objd_table.len)
105 return NULL;
106 if (!objd_table.array[id].u.s.f_count)
107 return NULL;
108 return &objd_table.array[id];
109 }
110
111 static
112 void *objd_private(int id)
113 {
114 struct obj *obj = _objd_get(id);
115 assert(obj);
116 return obj->u.s.private_data;
117 }
118
119 static
120 void objd_set_private(int id, void *private_data)
121 {
122 struct obj *obj = _objd_get(id);
123 assert(obj);
124 obj->u.s.private_data = private_data;
125 }
126
127 const struct objd_ops *objd_ops(int id)
128 {
129 struct obj *obj = _objd_get(id);
130
131 if (!obj)
132 return NULL;
133 return obj->u.s.ops;
134 }
135
136 static
137 void objd_free(int id)
138 {
139 struct obj *obj = _objd_get(id);
140
141 assert(obj);
142 obj->u.freelist_next = objd_table.freelist_head;
143 objd_table.freelist_head = obj - objd_table.array;
144 assert(obj->u.s.f_count == 1);
145 obj->u.s.f_count = 0; /* deallocated */
146 }
147
148 static
149 void objd_ref(int id)
150 {
151 struct obj *obj = _objd_get(id);
152 obj->u.s.f_count++;
153 }
154
155 int objd_unref(int id)
156 {
157 struct obj *obj = _objd_get(id);
158
159 if (!obj)
160 return -EINVAL;
161 if (obj->u.s.f_count == 1) {
162 ERR("Reference counting error\n");
163 return -EINVAL;
164 }
165 if ((--obj->u.s.f_count) == 1) {
166 const struct objd_ops *ops = objd_ops(id);
167
168 if (ops->release)
169 ops->release(id);
170 objd_free(id);
171 }
172 return 0;
173 }
174
175 static
176 void objd_table_destroy(void)
177 {
178 int i;
179
180 for (i = 0; i < objd_table.allocated_len; i++)
181 (void) objd_unref(i);
182 free(objd_table.array);
183 objd_table.array = NULL;
184 objd_table.len = 0;
185 objd_table.allocated_len = 0;
186 objd_table.freelist_head = -1;
187 }
188
189 /*
190 * This is LTTng's own personal way to create an ABI for sessiond.
191 * We send commands over a socket.
192 */
193
194 static const struct objd_ops lttng_ops;
195 static const struct objd_ops lttng_session_ops;
196 static const struct objd_ops lttng_channel_ops;
197 static const struct objd_ops lttng_metadata_ops;
198 static const struct objd_ops lttng_event_ops;
199 static const struct objd_ops lib_ring_buffer_objd_ops;
200
201 enum channel_type {
202 PER_CPU_CHANNEL,
203 METADATA_CHANNEL,
204 };
205
206 int lttng_abi_create_root_handle(void)
207 {
208 int root_handle;
209
210 root_handle = objd_alloc(NULL, &lttng_ops);
211 return root_handle;
212 }
213
214 static
215 int lttng_abi_create_session(void)
216 {
217 struct ltt_session *session;
218 int session_objd, ret;
219
220 session = ltt_session_create();
221 if (!session)
222 return -ENOMEM;
223 session_objd = objd_alloc(session, &lttng_session_ops);
224 if (session_objd < 0) {
225 ret = session_objd;
226 goto objd_error;
227 }
228 session->objd = session_objd;
229 return session_objd;
230
231 objd_error:
232 ltt_session_destroy(session);
233 return ret;
234 }
235
236 #if 0
237 static
238 int lttng_abi_tracepoint_list(void)
239 {
240 int list_objd, ret;
241
242 /* TODO: Create list private data */
243 list_objd = objd_alloc(NULL, &lttng_tracepoint_list_ops);
244 if (list_objd < 0) {
245 ret = list_objd;
246 goto objd_error;
247 }
248
249 return list_objd;
250
251 objd_error:
252 return ret;
253 }
254 #endif //0
255
256 static
257 long lttng_abi_tracer_version(int objd,
258 struct lttng_ust_tracer_version *v)
259 {
260 v->version = LTTNG_UST_VERSION;
261 v->patchlevel = LTTNG_UST_PATCHLEVEL;
262 v->sublevel = LTTNG_UST_SUBLEVEL;
263 return 0;
264 }
265
266 static
267 long lttng_abi_add_context(int objd,
268 struct lttng_ust_context *context_param,
269 struct lttng_ctx **ctx, struct ltt_session *session)
270 {
271 if (session->been_active)
272 return -EPERM;
273
274 switch (context_param->ctx) {
275 case LTTNG_UST_CONTEXT_PTHREAD_ID:
276 return lttng_add_pthread_id_to_ctx(ctx);
277 case LTTNG_UST_CONTEXT_VTID:
278 return lttng_add_vtid_to_ctx(ctx);
279 default:
280 return -EINVAL;
281 }
282 }
283
284 /**
285 * lttng_cmd - lttng control through socket commands
286 *
287 * @objd: the object descriptor
288 * @cmd: the command
289 * @arg: command arg
290 *
291 * This descriptor implements lttng commands:
292 * LTTNG_UST_SESSION
293 * Returns a LTTng trace session object descriptor
294 * LTTNG_UST_TRACER_VERSION
295 * Returns the LTTng kernel tracer version
296 * LTTNG_UST_TRACEPOINT_LIST
297 * Returns a file descriptor listing available tracepoints
298 * LTTNG_UST_WAIT_QUIESCENT
299 * Returns after all previously running probes have completed
300 *
301 * The returned session will be deleted when its file descriptor is closed.
302 */
303 static
304 long lttng_cmd(int objd, unsigned int cmd, unsigned long arg)
305 {
306 switch (cmd) {
307 case LTTNG_UST_SESSION:
308 return lttng_abi_create_session();
309 case LTTNG_UST_TRACER_VERSION:
310 return lttng_abi_tracer_version(objd,
311 (struct lttng_ust_tracer_version *) arg);
312 case LTTNG_UST_TRACEPOINT_LIST:
313 return -ENOSYS; //TODO
314 //return lttng_abi_tracepoint_list();
315 case LTTNG_UST_WAIT_QUIESCENT:
316 synchronize_trace();
317 return 0;
318 default:
319 return -EINVAL;
320 }
321 }
322
323 static const struct objd_ops lttng_ops = {
324 .cmd = lttng_cmd,
325 };
326
327 /*
328 * We tolerate no failure in this function (if one happens, we print a dmesg
329 * error, but cannot return any error, because the channel information is
330 * invariant.
331 */
332 static
333 void lttng_metadata_create_events(int channel_objd)
334 {
335 struct ltt_channel *channel = objd_private(channel_objd);
336 static struct lttng_ust_event metadata_params = {
337 .instrumentation = LTTNG_UST_TRACEPOINT,
338 .name = "lttng_metadata",
339 };
340 struct ltt_event *event;
341 int ret;
342
343 /*
344 * We tolerate no failure path after event creation. It will stay
345 * invariant for the rest of the session.
346 */
347 event = ltt_event_create(channel, &metadata_params, NULL);
348 if (!event) {
349 ret = -EINVAL;
350 goto create_error;
351 }
352 return;
353
354 create_error:
355 WARN_ON(1);
356 return; /* not allowed to return error */
357 }
358
359 int lttng_abi_create_channel(int session_objd,
360 struct lttng_ust_channel *chan_param,
361 enum channel_type channel_type)
362 {
363 struct ltt_session *session = objd_private(session_objd);
364 const struct objd_ops *ops;
365 const char *transport_name;
366 struct ltt_channel *chan;
367 int chan_objd;
368 int ret = 0;
369
370 chan_objd = objd_alloc(NULL, &lttng_channel_ops);
371 if (chan_objd < 0) {
372 ret = chan_objd;
373 goto objd_error;
374 }
375 switch (channel_type) {
376 case PER_CPU_CHANNEL:
377 if (chan_param->output == LTTNG_UST_MMAP) {
378 transport_name = chan_param->overwrite ?
379 "relay-overwrite-mmap" : "relay-discard-mmap";
380 } else {
381 return -EINVAL;
382 }
383 ops = &lttng_channel_ops;
384 break;
385 case METADATA_CHANNEL:
386 if (chan_param->output == LTTNG_UST_MMAP)
387 transport_name = "relay-metadata-mmap";
388 else
389 return -EINVAL;
390 ops = &lttng_metadata_ops;
391 break;
392 default:
393 transport_name = "<unknown>";
394 break;
395 }
396 /*
397 * We tolerate no failure path after channel creation. It will stay
398 * invariant for the rest of the session.
399 */
400 chan = ltt_channel_create(session, transport_name, NULL,
401 chan_param->subbuf_size,
402 chan_param->num_subbuf,
403 chan_param->switch_timer_interval,
404 chan_param->read_timer_interval,
405 &chan_param->shm_fd,
406 &chan_param->wait_fd,
407 &chan_param->memory_map_size);
408 if (!chan) {
409 ret = -EINVAL;
410 goto chan_error;
411 }
412 objd_set_private(chan_objd, chan);
413 chan->objd = chan_objd;
414 if (channel_type == METADATA_CHANNEL) {
415 session->metadata = chan;
416 lttng_metadata_create_events(chan_objd);
417 }
418
419 /* The channel created holds a reference on the session */
420 objd_ref(session_objd);
421
422 return chan_objd;
423
424 chan_error:
425 {
426 int err;
427
428 err = objd_unref(chan_objd);
429 assert(!err);
430 }
431 objd_error:
432 return ret;
433 }
434
435 /**
436 * lttng_session_cmd - lttng session object command
437 *
438 * @obj: the object
439 * @cmd: the command
440 * @arg: command arg
441 *
442 * This descriptor implements lttng commands:
443 * LTTNG_UST_CHANNEL
444 * Returns a LTTng channel object descriptor
445 * LTTNG_UST_ENABLE
446 * Enables tracing for a session (weak enable)
447 * LTTNG_UST_DISABLE
448 * Disables tracing for a session (strong disable)
449 * LTTNG_UST_METADATA
450 * Returns a LTTng metadata object descriptor
451 *
452 * The returned channel will be deleted when its file descriptor is closed.
453 */
454 static
455 long lttng_session_cmd(int objd, unsigned int cmd, unsigned long arg)
456 {
457 struct ltt_session *session = objd_private(objd);
458
459 switch (cmd) {
460 case LTTNG_UST_CHANNEL:
461 return lttng_abi_create_channel(objd,
462 (struct lttng_ust_channel *) arg,
463 PER_CPU_CHANNEL);
464 case LTTNG_UST_SESSION_START:
465 case LTTNG_UST_ENABLE:
466 return ltt_session_enable(session);
467 case LTTNG_UST_SESSION_STOP:
468 case LTTNG_UST_DISABLE:
469 return ltt_session_disable(session);
470 case LTTNG_UST_METADATA:
471 return lttng_abi_create_channel(objd,
472 (struct lttng_ust_channel *) arg,
473 METADATA_CHANNEL);
474 default:
475 return -EINVAL;
476 }
477 }
478
479 /*
480 * Called when the last file reference is dropped.
481 *
482 * Big fat note: channels and events are invariant for the whole session after
483 * their creation. So this session destruction also destroys all channel and
484 * event structures specific to this session (they are not destroyed when their
485 * individual file is released).
486 */
487 static
488 int lttng_release_session(int objd)
489 {
490 struct ltt_session *session = objd_private(objd);
491
492 if (session) {
493 ltt_session_destroy(session);
494 return 0;
495 } else {
496 return -EINVAL;
497 }
498 }
499
500 static const struct objd_ops lttng_session_ops = {
501 .release = lttng_release_session,
502 .cmd = lttng_session_cmd,
503 };
504
505 struct stream_priv_data {
506 struct lib_ring_buffer *buf;
507 struct ltt_channel *ltt_chan;
508 };
509
510 static
511 int lttng_abi_open_stream(int channel_objd, struct lttng_ust_stream *info)
512 {
513 struct ltt_channel *channel = objd_private(channel_objd);
514 struct lib_ring_buffer *buf;
515 struct stream_priv_data *priv;
516 int stream_objd, ret;
517
518 buf = channel->ops->buffer_read_open(channel->chan, channel->handle,
519 &info->shm_fd, &info->wait_fd, &info->memory_map_size);
520 if (!buf)
521 return -ENOENT;
522
523 priv = zmalloc(sizeof(*priv));
524 if (!priv) {
525 ret = -ENOMEM;
526 goto alloc_error;
527 }
528 priv->buf = buf;
529 priv->ltt_chan = channel;
530 stream_objd = objd_alloc(priv, &lib_ring_buffer_objd_ops);
531 if (stream_objd < 0) {
532 ret = stream_objd;
533 goto objd_error;
534 }
535 /* Hold a reference on the channel object descriptor */
536 objd_ref(channel_objd);
537 return stream_objd;
538
539 objd_error:
540 free(priv);
541 alloc_error:
542 channel->ops->buffer_read_close(buf, channel->handle);
543 return ret;
544 }
545
546 static
547 int lttng_abi_create_event(int channel_objd,
548 struct lttng_ust_event *event_param)
549 {
550 struct ltt_channel *channel = objd_private(channel_objd);
551 struct ltt_event *event;
552 int event_objd, ret;
553
554 event_param->name[LTTNG_UST_SYM_NAME_LEN - 1] = '\0';
555 event_objd = objd_alloc(NULL, &lttng_event_ops);
556 if (event_objd < 0) {
557 ret = event_objd;
558 goto objd_error;
559 }
560 /*
561 * We tolerate no failure path after event creation. It will stay
562 * invariant for the rest of the session.
563 */
564 event = ltt_event_create(channel, event_param, NULL);
565 if (!event) {
566 ret = -EINVAL;
567 goto event_error;
568 }
569 objd_set_private(event_objd, event);
570 /* The event holds a reference on the channel */
571 objd_ref(channel_objd);
572 return event_objd;
573
574 event_error:
575 {
576 int err;
577
578 err = objd_unref(event_objd);
579 assert(!err);
580 }
581 objd_error:
582 return ret;
583 }
584
585 /**
586 * lttng_channel_cmd - lttng control through object descriptors
587 *
588 * @objd: the object descriptor
589 * @cmd: the command
590 * @arg: command arg
591 *
592 * This object descriptor implements lttng commands:
593 * LTTNG_UST_STREAM
594 * Returns an event stream object descriptor or failure.
595 * (typically, one event stream records events from one CPU)
596 * LTTNG_UST_EVENT
597 * Returns an event object descriptor or failure.
598 * LTTNG_UST_CONTEXT
599 * Prepend a context field to each event in the channel
600 * LTTNG_UST_ENABLE
601 * Enable recording for events in this channel (weak enable)
602 * LTTNG_UST_DISABLE
603 * Disable recording for events in this channel (strong disable)
604 *
605 * Channel and event file descriptors also hold a reference on the session.
606 */
607 static
608 long lttng_channel_cmd(int objd, unsigned int cmd, unsigned long arg)
609 {
610 struct ltt_channel *channel = objd_private(objd);
611
612 switch (cmd) {
613 case LTTNG_UST_STREAM:
614 {
615 struct lttng_ust_stream *stream;
616
617 stream = (struct lttng_ust_stream *) arg;
618 /* stream used as output */
619 return lttng_abi_open_stream(objd, stream);
620 }
621 case LTTNG_UST_EVENT:
622 return lttng_abi_create_event(objd, (struct lttng_ust_event *) arg);
623 case LTTNG_UST_CONTEXT:
624 return lttng_abi_add_context(objd,
625 (struct lttng_ust_context *) arg,
626 &channel->ctx, channel->session);
627 case LTTNG_UST_ENABLE:
628 return ltt_channel_enable(channel);
629 case LTTNG_UST_DISABLE:
630 return ltt_channel_disable(channel);
631 default:
632 return -EINVAL;
633 }
634 }
635
636 /**
637 * lttng_metadata_cmd - lttng control through object descriptors
638 *
639 * @objd: the object descriptor
640 * @cmd: the command
641 * @arg: command arg
642 *
643 * This object descriptor implements lttng commands:
644 * LTTNG_UST_STREAM
645 * Returns an event stream file descriptor or failure.
646 *
647 * Channel and event file descriptors also hold a reference on the session.
648 */
649 static
650 long lttng_metadata_cmd(int objd, unsigned int cmd, unsigned long arg)
651 {
652 switch (cmd) {
653 case LTTNG_UST_STREAM:
654 {
655 struct lttng_ust_stream *stream;
656
657 stream = (struct lttng_ust_stream *) arg;
658 /* stream used as output */
659 return lttng_abi_open_stream(objd, stream);
660 }
661 default:
662 return -EINVAL;
663 }
664 }
665
666 #if 0
667 /**
668 * lttng_channel_poll - lttng stream addition/removal monitoring
669 *
670 * @file: the file
671 * @wait: poll table
672 */
673 unsigned int lttng_channel_poll(struct file *file, poll_table *wait)
674 {
675 struct ltt_channel *channel = file->private_data;
676 unsigned int mask = 0;
677
678 if (file->f_mode & FMODE_READ) {
679 poll_wait_set_exclusive(wait);
680 poll_wait(file, channel->ops->get_hp_wait_queue(channel->chan),
681 wait);
682
683 if (channel->ops->is_disabled(channel->chan))
684 return POLLERR;
685 if (channel->ops->is_finalized(channel->chan))
686 return POLLHUP;
687 if (channel->ops->buffer_has_read_closed_stream(channel->chan))
688 return POLLIN | POLLRDNORM;
689 return 0;
690 }
691 return mask;
692
693 }
694 #endif //0
695
696 static
697 int lttng_channel_release(int objd)
698 {
699 struct ltt_channel *channel = objd_private(objd);
700
701 if (channel)
702 return objd_unref(channel->session->objd);
703 return 0;
704 }
705
706 static const struct objd_ops lttng_channel_ops = {
707 .release = lttng_channel_release,
708 //.poll = lttng_channel_poll,
709 .cmd = lttng_channel_cmd,
710 };
711
712 static const struct objd_ops lttng_metadata_ops = {
713 .release = lttng_channel_release,
714 .cmd = lttng_metadata_cmd,
715 };
716
717 /**
718 * lttng_rb_cmd - lttng ring buffer control through object descriptors
719 *
720 * @objd: the object descriptor
721 * @cmd: the command
722 * @arg: command arg
723 *
724 * This object descriptor implements lttng commands:
725 * (None for now. Access is done directly though shm.)
726 * TODO: Add buffer flush.
727 */
728 static
729 long lttng_rb_cmd(int objd, unsigned int cmd, unsigned long arg)
730 {
731 //struct stream_priv_data *priv = objd_private(objd);
732
733 switch (cmd) {
734 default:
735 return -EINVAL;
736 }
737 }
738
739 static
740 int lttng_rb_release(int objd)
741 {
742 struct stream_priv_data *priv = objd_private(objd);
743 struct lib_ring_buffer *buf;
744 struct ltt_channel *channel;
745
746 if (priv) {
747 buf = priv->buf;
748 channel = priv->ltt_chan;
749 free(priv);
750 channel->ops->buffer_read_close(buf, channel->handle);
751
752 return objd_unref(channel->objd);
753 }
754 return 0;
755 }
756
757 static const struct objd_ops lib_ring_buffer_objd_ops = {
758 .release = lttng_rb_release,
759 .cmd = lttng_rb_cmd,
760 };
761
762 /**
763 * lttng_event_cmd - lttng control through object descriptors
764 *
765 * @objd: the object descriptor
766 * @cmd: the command
767 * @arg: command arg
768 *
769 * This object descriptor implements lttng commands:
770 * LTTNG_UST_CONTEXT
771 * Prepend a context field to each record of this event
772 * LTTNG_UST_ENABLE
773 * Enable recording for this event (weak enable)
774 * LTTNG_UST_DISABLE
775 * Disable recording for this event (strong disable)
776 */
777 static
778 long lttng_event_cmd(int objd, unsigned int cmd, unsigned long arg)
779 {
780 struct ltt_event *event = objd_private(objd);
781
782 switch (cmd) {
783 case LTTNG_UST_CONTEXT:
784 return lttng_abi_add_context(objd,
785 (struct lttng_ust_context *) arg,
786 &event->ctx, event->chan->session);
787 case LTTNG_UST_ENABLE:
788 return ltt_event_enable(event);
789 case LTTNG_UST_DISABLE:
790 return ltt_event_disable(event);
791 default:
792 return -EINVAL;
793 }
794 }
795
796 static
797 int lttng_event_release(int objd)
798 {
799 struct ltt_event *event = objd_private(objd);
800
801 if (event)
802 return objd_unref(event->chan->objd);
803 return 0;
804 }
805
806 /* TODO: filter control ioctl */
807 static const struct objd_ops lttng_event_ops = {
808 .release = lttng_event_release,
809 .cmd = lttng_event_cmd,
810 };
811
812 void lttng_ust_abi_exit(void)
813 {
814 objd_table_destroy();
815 }
This page took 0.045989 seconds and 5 git commands to generate.