summaryrefslogtreecommitdiffstats
path: root/README
blob: df985298aa8c73bdae539293cb2eb68dd221c656 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
REALTIMEKIT Realtime Policy and Watchdog Daemon

GIT:
        git://git.0pointer.de/rtkit.git

GITWEB:
        http://git.0pointer.de/?p=rtkit.git

NOTES:
        RealtimeKit is a D-Bus system service that changes the
        scheduling policy of user processes/threads to SCHED_RR
        (i.e. realtime scheduling mode) on request. It is intended to
        be used as a secure mechanism to allow real-time scheduling to
        be used by normal user processes.

        RealtimeKit enforces strict policies when handing out
        real-time security to user threads:

        * Only clients with RLIMIT_RTTIME set will get RT scheduling

        * RT scheduling will only be handed out to processes with
          SCHED_RESET_ON_FORK set to guarantee that the scheduling
          settings cannot 'leak' to child processes, thus making sure
          that 'RT fork bombs' cannot be used to bypass RLIMIT_RTTIME
          and take the system down.

        * Limits are enforced on all user controllable resources, only
          a maximum number of users, processes, threads can request RT
          scheduling at the same time.

        * Only a limited number of threads may be made RT in a
          specific time frame.

        * Client authorization is verified with PolicyKit

        RealtimeKit can also be used to hand outh high priority
        scheduling (i.e. negative nice level) to user processes.

        In addition to this a-priori policy enforcement, RealtimeKit
        also provides a-posteriori policy enforcement, i.e. it
        includes a canary-based watchdog that automatically demotes
        all real-time threads to SCHED_OTHER should the system
        overload despite the logic pointed out above. For more
        information regarding canary-based RT watchdogs, see the
        Acknowledgments section below.

        In its duty to manage real-time scheduling *securely*
        RealtimeKit runs as unpriviliged user, and uses capabalities,
        resource limits and chroot() to minimize its security impact.

        RealtimeKit probably has little use in embedded or server use
        cases, use RLIMIT_RTPRIO tehre instead.

WHY:
        If processes that have real-time scheduling privileges enter a
        busy loop they can freeze the entire the system. To make sure
        such run-away processes cannot do this RLIMIT_RTTIME has been
        introduced. Being a per-process limit it is however easily
        cirumvented by combining a fork bomb with a busy loop.

        RealtimeKit hands out RT scheduling to specific threads that
        ask for it -- but only to those and due to SCHED_RESET_ON_FORK
        it can be sure that this won't 'leak'.

        In contrast to RLIMIT_RTPRIO the RealtimeKit logic makes sure
        that only a certain number of threads can be made realtime,
        per user, per process and per time interval.


CLIENTS:
        To be able to make use of realtime scheduling clients may
        request so with a small D-Bus interface that is accessible on
        the interface org.freedesktop.RealtimeKit1 as object
        /org/freedesktop/RealtimeKit1 on the service
        org.freedesktop.RealtimeKit1:

                void MakeThreadRealtime(u64 thread_id, u32 priority);

                void MakeThreadHighPriority(u64 thread_id, s32 priority);

        The thread IDs need to be passed as kernel tids as returned by
        gettid(), not a pthread_t! Only threads belonging to the
        calling process can be made realtime/high priority. (Please
        note that gettid() is not available in glibc, you need to
        implement that manually using syscall(). Consult the reference
        client implementation for details.)

        A BSD-licensed reference implementation of the client is
        available in rtkit.[ch] as part of the package. You may copy
        this into your sources if you wish. However given how simple
        the D-Bus interface is you might choose to implement your own
        client implementation.

        It is advisable to try acquiring realtime scheduling with
        sched_setsheduler() first, so that systems where RLIMIT_RTPRIO
        is set can be supported.

        Here's an example using the reference implementation. Replace
        this:

        <snip>
                struct sched_param p;
                memset(&p, 0, sizeof(p));
                p.sched_priority = 3;
                sched_setscheduler(0, SCHED_RR|SCHED_RESET_ON_FORK, &p);
        </snip>

        by this:

        <snip>
                struct sched_param p;
                memset(&p, 0, sizeof(p));
                p.sched_priority = 3;
                if (sched_setscheduler(0, SCHED_RR|SCHED_RESET_ON_FORK, &p) < 0
                        && errno == EPERM)
                        rtkit_make_realtime(system_bus, 0, p.sched_priority);
        </snip>

        But of course add more appropriate error checking! Also,
        falling back to plain SCHED_RR when SCHED_RESET_ON_FORK causes
        EINVAL migt be advisable).

DAEMON:

        The daemon is automatically started on first use via D-Bus
        system bus activation.

        Currently the daemon does not read on any configuration file,
        however it can be configured with command line parameters. You
        can edit

        /usr/share/dbus-1/system-services/org.freedesktop.RealtimeKit1.service

        to set those.

        Run

        /usr/libexec/rtkit-daemon --help

        to get a quick overview on the supported parameters and their
        defaults. Many of them should be obvious in their meaning. For
        the remaining ones see below:

        --max-realtime-priority= may be used to specify the maximum
        realtime priority a client can acquire through
        RealtimeKit. Please note that this value must be smaller than
        the value passed to --our-realtime-priority=.

        --our-realtime-priority= may be used to specify the realtime
        priority of the daemon itself. Please note that this priority
        is only used for a very short time while processing a client
        request. Normally the daemon will not be running with a
        realtime scheduling policy. The real-time priorities handed
        out to the user must be lower than this value. (see above).

        --min-nice-level= may be used to specify the minimum nice
        level a client can acquire through RealtimeKit.

        --our-nice-level= may be used to specify the nice level the
        the daemon itself uses most of the time (except when
        processing requests, see above). It is probably a good idea to
        set this to a small positive value, to make sure that if the
        system is overloaded already handing out further RT scheduling
        will be delayed a bit.

        --rttime-usec-max= may be used to control which RLIMIT_RTTIME
        value clients need to have chosen at minumum before they may
        acquire RT scheduling through RealtimeKit.

        --users-max= specifies how many users may acquire RT
        scheduling at the same time for one or multiple of their
        processes.

        --processes-per-user-max= specifies how many processes per
        user may acquire RT scheduling at the same time.

        --threads-per-user-max= specifies how many threads per user
        may acquire RT scheduling at the same time. Of course this
        value should be set higher than --process-per-user-max=.

        --actions-burst-sec= may be used to influence the rate
        limiting logic in RealtimeKit. The daemon will only pass
        realtime scheduling privileges to a maximum number of threads
        within this timeframe (see below).

        --actions-per-burst-max= may be used to influence the rate
        limiting logic in RealtimeKit. The daemon will only pass
        realtime scheduling privileges to this number of threads
        within the time frame configured via
        --actions-burst-sec=. When this limit is reached clients need
        to wait until that time passes before requesting RT scheduling
        again.

        --canary-cheep-msec= may be used to control how often the
        canary thread shall cheep.

        --canary-watchdog-msec= may be used to control how quickly the
        watchdog thread expects to receive a cheep from the canary
        thread. This value must be chosen larger than
        --canary-cheep-msec=. If the former is set 10s and the latter
        to 7s, then the canary thread can trigger and deliver the
        cheep with a maximum latency of 3s.

ACKNOWLEDGMENTS:
        The canary watchdog logic is inspired by previous work of
        Vernon Mauery, Florian Schmidt, Kjetil Matheussen:

        http://rt.wiki.kernel.org/index.php/RT_Watchdog

LICENSE:
        GPLv3+ for the daemon
        BSD for the client reference implementation

AUTHOR:
        Lennart Poettering

REQUIREMENTS:
        Linux kernel >= 2.6.31
        D-Bus
        PolicyKit >= 0.92