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