Fix: unchecked return value in trace_clock_read64_monotonic
[lttng-tools.git] / doc / relayd-architecture.txt
1LTTng Relay Daemon Architecture
2Mathieu Desnoyers, August 2015
4This document describes the object model and architecture of the relay
5daemon, after the refactoring done within the commit "Fix: Relay daemon
6ownership and reference counting".
8We have the following object composition hierarchy:
10relay connection (main.c, for sessiond/consumer)
11 |
12 \-> 0 or 1 session
13 |
14 \-> 0 or many ctf-trace
15 |
16 \-> 0 or many stream
17 | |
18 | \-> 0 or many index
19 |
20 \-------> 0 or 1 viewer stream
22live connection (live.c, for client)
23 |
24 \-> 1 viewer session
25 |
26 \-> 0 or many session (actually a reference to session as created
27 | by the relay connection)
28 |
29 \-> ..... (ctf-trace, stream, index, viewer stream)
31There are global tables declared in lttng-relayd.h for sessions
32(sessions_ht, indexed by session id), streams (relay_streams_ht, indexed
33by stream handle), and viewer streams (viewer_streams_ht, indexed by
34stream handle). The purpose of those tables is to allow fast lookup of
35those objects using the IDs received in the communication protocols.
37There is also one connection hash table per worker thread. There is one
38worker thread to receive data (main.c), and one worker thread to
39interact with viewer clients (live.c). Those tables are indexed by
40socket file descriptor.
42A RCU lookup+refcounting scheme has been introduced for all objects
43(except viewer session which is still an exception at the moment). This
44scheme allows looking up the objects or doing a traversal on the RCU
45linked list or hash table in combination with a getter on the object.
46This getter validates that there is still at least one reference to the
47object, else the lookup acts just as if the object does not exist. This
48scheme is protected by a "reflock" mutex in each object. "reflock"
49mutexes can be nested from the innermost object to the outermost object.
50IOW, the session reflock can nest within the ctf-trace reflock.
52The relay_connection (connection between the sessiond/consumer and the
53relayd) is the outermost object of its hierarchy.
55The live connection (connection between a live client and the relayd)
56is the outermost object of its hierarchy.
58There is also a "lock" mutex in each object. Those are used to
59synchronize between threads (currently the main.c relay thread and
60live.c client thread) when objects are shared. Locks can be nested from
61the outermost object to the innermost object. IOW, the ctf-trace lock can
62nest within the session lock.
64A "lock" should never nest within a "reflock".
66RCU linked lists are used to iterate using RCU, and are protected by
67their own mutex for modifications. Iterations should be confirmed using
68the object "getter" to ensure its refcount is not 0 (except in cases
69where the caller actually owns the objects and therefore can assume its
70refcount is not 0).
72RCU hash tables are used to iterate using RCU. Iteration should be
73confirmed using the object "getter" to ensure its refcount is not 0
74(except again if we have ownership and can assume the object refcount is
75not 0).
77Object creation has a refcount of 1. Each getter increments the
78refcount, and needs to be paired with a "put" to decrement it. A final
79put on "self" (ownership) will allow refcount to reach 0, therefore
80triggering release, and thus free through call_rcu.
82In the composition scheme, we find back references from each composite
83to its container. Therefore, each composite holds a reference (refcount)
84on its container. This allows following pointers from e.g. viewer stream
85to stream to ctf-trace to session without performing any validation,
86due to transitive refcounting of those back-references.
88In addition to those back references, there are a few key ownership
89references held. The connection in the relay worker thread (main.c)
90holds ownership on the session, and on each stream it contains. The
91connection in the live worker thread (live.c) holds ownership on each
92viewer stream it creates. The rest is ensured by back references from
93composite to container objects. When a connection is closed, it puts all
94the ownership references it is holding. This will then eventually
95trigger destruction of the session, streams, and viewer streams
96associated with the connection when all the back references reach 0.
98RCU read-side locks are now only held during iteration on RCU lists and
99hash tables, and within the internals of the get (lookup) and put
100functions. Those functions then use refcounting to ensure existence of
101the object when returned to their caller.
This page took 0.036625 seconds and 4 git commands to generate.