Class: OsCtld::Devices::GroupManager
- Inherits:
-
Manager
- Object
- Manager
- OsCtld::Devices::GroupManager
show all
- Includes:
- OsCtl::Lib::Utils::Log
- Defined in:
- lib/osctld/devices/group_manager.rb
Instance Attribute Summary
Attributes inherited from Manager
#devices, #owner
Instance Method Summary
collapse
-
#add(device, parent = nil) ⇒ Object
-
#apply(parents: true, descendants: false, containers: false) ⇒ Object
Apply cgroup parameters of the group and all its parents.
-
#can_unset_inherit?(device) ⇒ Boolean
protected
Check if the inheritance can be disabled.
-
#check_descendant_mode!(entity, device, mode) ⇒ Object
protected
-
#check_descendants!(device, mode: nil) ⇒ Object
-
#chmod(device, mode, opts = {}) ⇒ Object
-
#do_update_inherited_descendants(device, mode, changes) ⇒ Object
protected
-
#inherit(device, opts = {}) ⇒ Object
-
#inherit_promoted(device) ⇒ Object
-
#inherit_recursive(device) ⇒ Object
Add the device to all direct child groups and containers, then let the child groups do the same.
-
#init(opts = {}) ⇒ Object
-
#provide(device) ⇒ Object
Add device to make it available to child groups.
-
#remove(device) ⇒ Object
-
#remove_recursive(device) ⇒ Object
Remove device from self and all descendants.
-
#set_inherit(device) ⇒ Object
-
#uninherit_recursive(device) ⇒ Object
Remove the device from all direct child groups and containers, then let the child groups do the same.
-
#unset_inherit(device) ⇒ Object
-
#update_inherited_mode(device, mode, changes) ⇒ Object
-
#used_by_descendants?(device) ⇒ Boolean
Methods inherited from Manager
#add_new, #check_availability!, #clear, #detect, #do_add, #do_allow_dev, #do_apply_changes, #do_deny_all, #do_deny_dev, #dump, #dup, #each, #export, #find, #get, #include?, #inherit_all_from, #initialize, load, #promote, #replace, #select, #sync, #used?
Instance Method Details
#add(device, parent = nil) ⇒ Object
58
59
60
61
62
63
64
65
66
67
68
69
70
|
# File 'lib/osctld/devices/group_manager.rb', line 58
def add(device, parent = nil)
sync do
super
if device.inherit?
group.descendants.each { |grp| grp.devices.inherit(device) }
group.containers.each do |ct|
ct.devices.inherit(device)
end
end
end
end
|
#apply(parents: true, descendants: false, containers: false) ⇒ Object
Apply cgroup parameters of the group and all its parents
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
|
# File 'lib/osctld/devices/group_manager.rb', line 246
def apply(parents: true, descendants: false, containers: false)
sync do
if parents
group.parents.each do |grp|
grp.devices.apply(parents: false)
end
end
super()
if descendants
group.descendants.each do |grp|
grp.devices.apply(parents: false, descendants: false, containers: containers)
end
end
if containers
group.containers.each do |ct|
ct.devices.apply
end
end
end
end
|
#can_unset_inherit?(device) ⇒ Boolean
Check if the inheritance can be disabled
We have to forbid disabling the inheritance if a container has the device promoted, but its group does not. Thus, the device cannot be deleted from the group, because the container needs it. The same applies for promoted group devices.
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
|
# File 'lib/osctld/devices/group_manager.rb', line 342
def can_unset_inherit?(device)
group.containers.each do |ct|
return false if ct.devices.used?(device)
end
group.descendants.each do |grp|
dev = grp.devices.get(device)
parent = grp.parent
if parent != group
pdev = parent.devices.get(device)
next if !pdev.inherited?
return false if grp.devices.used?(device)
end
next unless dev.inherited?
grp.containers.each do |ct|
return false if ct.devices.used?(device)
end
end
true
end
|
#check_descendant_mode!(entity, device, mode) ⇒ Object
311
312
313
314
315
316
|
# File 'lib/osctld/devices/group_manager.rb', line 311
def check_descendant_mode!(entity, device, mode)
dev = entity.devices.get(device)
return if !dev || mode.compatible?(dev.mode)
raise DeviceDescendantRequiresMode.new(entity, dev.mode)
end
|
#check_descendants!(device, mode: nil) ⇒ Object
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
|
# File 'lib/osctld/devices/group_manager.rb', line 270
def check_descendants!(device, mode: nil)
sync do
group.descendants.each do |grp|
check_descendant_mode!(grp, device, mode || device.mode)
grp.containers.each do |ct|
check_descendant_mode!(ct, device, mode || device.mode)
end
end
group.containers.each do |ct|
check_descendant_mode!(ct, device, mode || device.mode)
end
end
end
|
#chmod(device, mode, opts = {}) ⇒ Object
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
|
# File 'lib/osctld/devices/group_manager.rb', line 109
def chmod(device, mode, opts = {})
sync do
if opts[:parents]
dev = device.clone
dev.mode = mode
group.parent.devices.provide(dev)
end
changes = super
if opts[:descendants]
group.descendants.each do |grp|
dev = grp.devices.get(device)
grp.devices.chmod(dev, mode, containers: true) if dev
end
end
if opts[:containers]
group.containers.each do |ct|
dev = ct.devices.get(device)
ct.devices.chmod(dev, mode, group_changes: changes) if dev
end
end
end
end
|
#do_update_inherited_descendants(device, mode, changes) ⇒ Object
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
|
# File 'lib/osctld/devices/group_manager.rb', line 318
def do_update_inherited_descendants(device, mode, changes)
group.children.each do |grp|
cdev = grp.devices.get(device)
next unless cdev.inherited?
grp.devices.update_inherited_mode(cdev, mode.clone, changes)
end
group.containers.each do |ct|
cdev = ct.devices.get(device)
next unless cdev.inherited?
ct.devices.update_inherited_mode(cdev, mode.clone, changes)
end
end
|
#inherit(device, opts = {}) ⇒ Object
72
73
74
75
76
77
78
79
80
|
# File 'lib/osctld/devices/group_manager.rb', line 72
def inherit(device, opts = {})
sync do
super
group.containers.each do |ct|
ct.devices.inherit(device)
end
end
end
|
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
|
# File 'lib/osctld/devices/group_manager.rb', line 139
def inherit_promoted(device)
sync do
pdev = group.parent.devices.get(device) unless group.root?
if pdev && pdev.inherit?
device.inherited = true
if device.mode != pdev.mode
changes = device.chmod(pdev.mode.clone)
do_apply_changes(changes)
do_update_inherited_descendants(device, pdev.mode, changes)
end
group.save_config
return
end
if used_by_descendants?(device)
raise DeviceInUse,
'the device would be removed, but child groups or containers '+
'are using it'
end
remove_recursive(device)
end
end
|
#inherit_recursive(device) ⇒ Object
Add the device to all direct child groups and containers, then let the child groups do the same
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
|
# File 'lib/osctld/devices/group_manager.rb', line 204
def inherit_recursive(device)
sync do
group.descendants.each do |grp|
next if grp.parent != group || grp.devices.include?(device)
grp.devices.inherit(device)
grp.devices.apply(parents: false)
grp.devices.inherit_recursive(device)
end
group.containers.each do |ct|
ct.devices.apply
end
end
end
|
#init(opts = {}) ⇒ Object
8
9
10
11
12
13
14
15
16
17
18
|
# File 'lib/osctld/devices/group_manager.rb', line 8
def init(opts = {})
sync do
super
inherit_all_from(group.parent, opts) unless group.root?
log(:info, group, "Configuring cgroup #{group.cgroup_path} for devices")
if CGroup.mkpath('devices', group.cgroup_path.split('/'))
apply(parents: false)
end
end
end
|
#provide(device) ⇒ Object
Add device to make it available to child groups
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
|
# File 'lib/osctld/devices/group_manager.rb', line 22
def provide(device)
sync do
dev = get(device)
if dev
return if dev.mode.compatible?(device.mode)
dev.mode.complement(device.mode)
group.parent.devices.provide(device) unless group.root?
apply(parents: false)
group.save_config
return
end
group.parent.devices.provide(device) unless group.root?
dev = device.clone
dev.inherit = false
do_add(dev)
apply(parents: false)
group.save_config
end
end
|
#remove(device) ⇒ Object
82
83
84
85
86
87
88
89
90
|
# File 'lib/osctld/devices/group_manager.rb', line 82
def remove(device)
sync do
super
group.containers.each do |ct|
ct.devices.remove(device)
end
end
end
|
#remove_recursive(device) ⇒ Object
Remove device from self and all descendants
94
95
96
97
98
99
100
101
102
103
|
# File 'lib/osctld/devices/group_manager.rb', line 94
def remove_recursive(device)
sync do
group.descendants.reverse_each do |grp|
dev = grp.devices.get(device)
grp.devices.remove(dev) if dev
end
remove(device)
end
end
|
#set_inherit(device) ⇒ Object
181
182
183
184
185
186
187
|
# File 'lib/osctld/devices/group_manager.rb', line 181
def set_inherit(device)
sync do
device.inherit = true
inherit_recursive(device)
owner.save_config
end
end
|
#uninherit_recursive(device) ⇒ Object
Remove the device from all direct child groups and containers, then let the child groups do the same
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
|
# File 'lib/osctld/devices/group_manager.rb', line 226
def uninherit_recursive(device)
sync do
group.descendants.each do |grp|
next if grp.parent != group || grp.devices.used?(device)
grp.devices.uninherit_recursive(device)
grp.devices.remove(device)
end
group.containers.each do |ct|
next if ct.devices.used?(device)
ct.devices.remove(device)
end
end
end
|
#unset_inherit(device) ⇒ Object
189
190
191
192
193
194
195
196
197
198
199
200
|
# File 'lib/osctld/devices/group_manager.rb', line 189
def unset_inherit(device)
sync do
unless can_unset_inherit?(device)
raise DeviceInUse,
'unsetting inheritance would break device access requirements'
end
device.inherit = false
uninherit_recursive(device)
owner.save_config
end
end
|
#update_inherited_mode(device, mode, changes) ⇒ Object
171
172
173
174
175
176
177
178
179
|
# File 'lib/osctld/devices/group_manager.rb', line 171
def update_inherited_mode(device, mode, changes)
sync do
super
do_update_inherited_descendants(device, mode, changes)
end
end
|
#used_by_descendants?(device) ⇒ Boolean
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
|
# File 'lib/osctld/devices/group_manager.rb', line 290
def used_by_descendants?(device)
sync do
group.descendants.each do |grp|
return true if grp.devices.used?(device)
grp.containers.each do |ct|
return true if ct.devices.used?(device)
end
end
group.containers.each do |ct|
return true if ct.devices.used?(device)
end
false
end
end
|