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
|
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.
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.
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).
ACKNOWLEDGMENTS:
The 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
|