0
# Resource Controllers
1
2
Controller classes providing typed access to cgroup resource management files. Controllers automatically handle data conversion between Python objects and cgroup-compatible strings, enabling pythonic management of system resources.
3
4
## Capabilities
5
6
### Base Controller
7
8
Base controller class providing common functionality for all cgroup property management with file interface abstractions.
9
10
```python { .api }
11
class Controller:
12
"""Base controller for cgroup property access and file management."""
13
14
# Common properties available to all controllers
15
tasks: List[int] # Task IDs in cgroup
16
procs: List[int] # Process IDs in cgroup
17
notify_on_release: bool # Notify on release flag
18
clone_children: bool # Clone children flag
19
20
def __init__(self, node):
21
"""
22
Initialize controller for a specific node.
23
24
Parameters:
25
- node: Node, the cgroup node this controller manages
26
"""
27
28
def filepath(self, filename: str) -> bytes:
29
"""
30
Get full path to a cgroup control file.
31
32
Parameters:
33
- filename: str, name of the control file
34
35
Returns:
36
Full filesystem path to the file
37
"""
38
39
def list_interfaces(self) -> list:
40
"""
41
List all available file interfaces for this controller.
42
43
Returns:
44
List of interface names available for this controller
45
"""
46
47
def get_interface(self, key):
48
"""
49
Get file interface object by key name.
50
51
Parameters:
52
- key: str, interface key name
53
54
Returns:
55
BaseFileInterface object for the specified interface
56
"""
57
58
def get_property(self, filename: str) -> str:
59
"""
60
Read raw string value from a cgroup control file.
61
62
Parameters:
63
- filename: str, control file name
64
65
Returns:
66
Raw string content of the file
67
68
Raises:
69
OSError if file doesn't exist or cannot be read
70
"""
71
72
def get_content(self, key):
73
"""
74
Get processed content using file interface by key.
75
76
Parameters:
77
- key: str, interface key name
78
79
Returns:
80
Processed content based on interface type (int, dict, list, etc.)
81
"""
82
83
def set_property(self, filename: str, value) -> int:
84
"""
85
Write value to a cgroup control file.
86
87
Parameters:
88
- filename: str, control file name
89
- value: any, value to write (converted to string)
90
91
Returns:
92
Number of bytes written
93
94
Raises:
95
OSError if file cannot be written
96
"""
97
```
98
99
### CPU Controller
100
101
CPU scheduling and bandwidth management with CFS (Completely Fair Scheduler) and RT (Real-Time) parameters.
102
103
```python { .api }
104
class CpuController(Controller):
105
"""CPU cgroup controller for scheduling and bandwidth management."""
106
107
# CFS (Completely Fair Scheduler) parameters
108
cfs_period_us: int # CFS period in microseconds
109
cfs_quota_us: int # CFS quota in microseconds (-1 for unlimited)
110
111
# RT (Real-Time) parameters
112
rt_period_us: int # RT period in microseconds
113
rt_runtime_us: int # RT runtime in microseconds
114
115
# CPU shares for proportional scheduling
116
shares: int # CPU shares (default: 1024)
117
118
# Statistics
119
stat: dict # CPU usage statistics
120
```
121
122
Usage example:
123
124
```python
125
from cgroupspy.trees import Tree
126
127
# Get CPU controller
128
t = Tree()
129
cpu_node = t.get_node_by_path('/cpu/test/')
130
131
# Set CPU quota (50% of one CPU core)
132
cpu_node.controller.cfs_period_us = 100000 # 100ms
133
cpu_node.controller.cfs_quota_us = 50000 # 50ms
134
135
# Set CPU shares (relative weight)
136
cpu_node.controller.shares = 512 # Half the default weight
137
138
# Check statistics
139
stats = cpu_node.controller.stat
140
print(stats['nr_periods']) # Number of periods
141
print(stats['nr_throttled']) # Number of throttled periods
142
```
143
144
### CPU Accounting Controller
145
146
CPU usage tracking and per-CPU statistics for monitoring and accounting purposes.
147
148
```python { .api }
149
class CpuAcctController(Controller):
150
"""CPU accounting controller for usage tracking."""
151
152
# Usage statistics
153
usage: int # Total CPU usage in nanoseconds
154
usage_percpu: List[int] # Per-CPU usage in nanoseconds
155
156
# Detailed statistics
157
stat: dict # CPU accounting statistics (user/system time)
158
```
159
160
Usage example:
161
162
```python
163
from cgroupspy.trees import Tree
164
165
# Get CPU accounting controller
166
t = Tree()
167
cpuacct_node = t.get_node_by_path('/cpuacct/test/')
168
169
# Read usage statistics
170
total_usage = cpuacct_node.controller.usage # Total nanoseconds
171
per_cpu = cpuacct_node.controller.usage_percpu # Per-CPU usage
172
173
# Get detailed statistics
174
stat = cpuacct_node.controller.stat
175
print(f"User time: {stat['user']}")
176
print(f"System time: {stat['system']}")
177
```
178
179
### CPU Set Controller
180
181
CPU and memory node assignment for NUMA-aware process placement and CPU pinning.
182
183
```python { .api }
184
class CpuSetController(Controller):
185
"""CPU set controller for CPU and memory node assignment."""
186
187
# Core assignments
188
cpus: set # Set of allowed CPU cores
189
mems: set # Set of allowed memory nodes
190
191
# Inheritance and spreading flags
192
cpu_exclusive: bool # Exclusive CPU access
193
mem_exclusive: bool # Exclusive memory access
194
mem_hardwall: bool # Hard memory wall
195
memory_migrate: bool # Migrate memory on CPU change
196
memory_pressure_enabled: bool # Enable memory pressure notifications
197
memory_spread_page: bool # Spread page cache
198
memory_spread_slab: bool # Spread slab cache
199
sched_load_balance: bool # Enable scheduler load balancing
200
sched_relax_domain_level: int # Scheduler domain relaxation level
201
```
202
203
Usage example:
204
205
```python
206
from cgroupspy.trees import Tree
207
208
# Get CPU set controller
209
t = Tree()
210
cpuset_node = t.get_node_by_path('/cpuset/test/')
211
212
# Pin to specific CPUs
213
cpuset_node.controller.cpus = {0, 1, 2, 3} # CPUs 0-3
214
cpuset_node.controller.mems = {0} # Memory node 0
215
216
# Enable exclusive access
217
cpuset_node.controller.cpu_exclusive = True
218
cpuset_node.controller.mem_exclusive = True
219
220
# Configure memory policies
221
cpuset_node.controller.memory_migrate = True
222
cpuset_node.controller.memory_spread_page = True
223
```
224
225
### Memory Controller
226
227
Memory usage limits, statistics, and OOM (Out-of-Memory) control for resource management.
228
229
```python { .api }
230
class MemoryController(Controller):
231
"""Memory controller for usage limits and statistics."""
232
233
# Memory limits and usage
234
limit_in_bytes: int # Memory limit in bytes (-1 for unlimited)
235
usage_in_bytes: int # Current memory usage in bytes
236
max_usage_in_bytes: int # Maximum memory usage reached
237
238
# Kernel memory (if enabled)
239
kmem_limit_in_bytes: int # Kernel memory limit
240
kmem_usage_in_bytes: int # Kernel memory usage
241
242
# Swap control
243
memsw_limit_in_bytes: int # Memory + swap limit
244
memsw_usage_in_bytes: int # Memory + swap usage
245
memsw_max_usage_in_bytes: int # Maximum memory + swap usage
246
247
# OOM control
248
oom_control: dict # OOM killer control settings
249
250
# Memory pressure notifications
251
pressure_level: int # Memory pressure level
252
253
# Statistics
254
stat: dict # Detailed memory statistics
255
256
# Control flags
257
swappiness: int # Swappiness value (0-100)
258
move_charge_at_immigrate: int # Charge movement on task migration
259
use_hierarchy: bool # Use hierarchical accounting
260
```
261
262
Usage example:
263
264
```python
265
from cgroupspy.trees import Tree
266
267
# Get memory controller
268
t = Tree()
269
mem_node = t.get_node_by_path('/memory/test/')
270
271
# Set memory limit (1GB)
272
mem_node.controller.limit_in_bytes = 1024 * 1024 * 1024
273
274
# Set swap limit (2GB total)
275
mem_node.controller.memsw_limit_in_bytes = 2 * 1024 * 1024 * 1024
276
277
# Configure swappiness
278
mem_node.controller.swappiness = 10 # Low swappiness
279
280
# Check current usage
281
current = mem_node.controller.usage_in_bytes
282
limit = mem_node.controller.limit_in_bytes
283
print(f"Memory usage: {current / (1024**3):.2f} GB / {limit / (1024**3):.2f} GB")
284
285
# Check OOM status
286
oom = mem_node.controller.oom_control
287
print(f"OOM disabled: {oom['oom_kill_disable']}")
288
```
289
290
### Device Controller
291
292
Device access control with allow/deny rules for character and block devices.
293
294
```python { .api }
295
class DevicesController(Controller):
296
"""Device access controller for device permissions."""
297
298
# Device access control
299
allow: str # Allow device access (write-only)
300
deny: str # Deny device access (write-only)
301
list: str # List current device permissions (read-only)
302
```
303
304
Usage example:
305
306
```python
307
from cgroupspy.trees import Tree
308
from cgroupspy.contenttypes import DeviceAccess
309
310
# Get devices controller
311
t = Tree()
312
devices_node = t.get_node_by_path('/devices/test/')
313
314
# Allow access to specific device
315
# Format: "type major:minor permissions"
316
devices_node.controller.allow = "c 1:5 rwm" # /dev/console
317
318
# Using DeviceAccess helper
319
access = DeviceAccess(
320
dev_type=DeviceAccess.TYPE_CHAR,
321
major=1, minor=5,
322
access=DeviceAccess.ACCESS_READ | DeviceAccess.ACCESS_WRITE
323
)
324
devices_node.controller.allow = str(access)
325
326
# Deny access to all devices
327
devices_node.controller.deny = "all" # Deny all
328
329
# List current permissions
330
permissions = devices_node.controller.list
331
print(permissions)
332
```
333
334
### Block I/O Controller
335
336
Block device I/O throttling, bandwidth control, and statistics for storage resource management.
337
338
```python { .api }
339
class BlkIOController(Controller):
340
"""Block I/O controller for bandwidth control and throttling."""
341
342
# Weight-based bandwidth control
343
weight: int # I/O weight (100-1000)
344
weight_device: str # Per-device I/O weights
345
346
# Throttling controls
347
throttle_read_bps_device: str # Read bandwidth throttling
348
throttle_write_bps_device: str # Write bandwidth throttling
349
throttle_read_iops_device: str # Read IOPS throttling
350
throttle_write_iops_device: str # Write IOPS throttling
351
352
# Statistics
353
time: dict # I/O time statistics
354
sectors: dict # I/O sector statistics
355
io_service_bytes: dict # I/O service bytes
356
io_serviced: dict # I/O operations serviced
357
io_service_time: dict # I/O service time
358
io_wait_time: dict # I/O wait time
359
io_merged: dict # I/O merged operations
360
io_queued: dict # I/O queued operations
361
362
# Reset controls
363
reset_stats: int # Reset statistics (write-only)
364
```
365
366
Usage example:
367
368
```python
369
from cgroupspy.trees import Tree
370
371
# Get Block I/O controller
372
t = Tree()
373
blkio_node = t.get_node_by_path('/blkio/test/')
374
375
# Set I/O weight
376
blkio_node.controller.weight = 500 # Medium priority
377
378
# Throttle read bandwidth (10MB/s on device 8:0)
379
blkio_node.controller.throttle_read_bps_device = "8:0 10485760"
380
381
# Throttle write IOPS (1000 IOPS on device 8:0)
382
blkio_node.controller.throttle_write_iops_device = "8:0 1000"
383
384
# Check I/O statistics
385
stats = blkio_node.controller.io_service_bytes
386
for device, bytes_stats in stats.items():
387
print(f"Device {device}: Read {bytes_stats['Read']} bytes")
388
```
389
390
### Network Classifier Controller
391
392
Network packet classification tagging for Quality of Service (QoS) and traffic shaping integration.
393
394
```python { .api }
395
class NetClsController(Controller):
396
"""Network classifier controller for packet tagging."""
397
398
classid: int # Network class ID for packet tagging
399
```
400
401
Usage example:
402
403
```python
404
from cgroupspy.trees import Tree
405
406
# Get network classifier controller
407
t = Tree()
408
netcls_node = t.get_node_by_path('/net_cls/test/')
409
410
# Set class ID for packet tagging
411
netcls_node.controller.classid = 0x10001 # Class ID for tc/iptables
412
```
413
414
### Network Priority Controller
415
416
Network interface priority mapping for controlling network bandwidth allocation per interface.
417
418
```python { .api }
419
class NetPrioController(Controller):
420
"""Network priority controller for interface priority mapping."""
421
422
prioidx: int # Priority index
423
ifpriomap: dict # Interface priority mapping
424
```
425
426
Usage example:
427
428
```python
429
from cgroupspy.trees import Tree
430
431
# Get network priority controller
432
t = Tree()
433
netprio_node = t.get_node_by_path('/net_prio/test/')
434
435
# Set priority index
436
netprio_node.controller.prioidx = 1
437
438
# Set interface priorities
439
netprio_node.controller.ifpriomap = {
440
"eth0": 5, # High priority
441
"eth1": 1 # Low priority
442
}
443
```
444
445
## Types
446
447
```python { .api }
448
# File interface base classes
449
class BaseFileInterface:
450
"""Base interface for cgroup file access with type conversion."""
451
readonly: bool
452
writeonly: bool
453
454
def __init__(self, filename: str, readonly=None, writeonly=None): ...
455
def sanitize_get(self, value: str): ...
456
def sanitize_set(self, value): ...
457
458
class FlagFile(BaseFileInterface):
459
"""Boolean flag file interface (0/1 to False/True)."""
460
461
class IntegerFile(BaseFileInterface):
462
"""Integer file interface with automatic conversion."""
463
464
class DictFile(BaseFileInterface):
465
"""Dictionary file interface for key-value files."""
466
467
class ListFile(BaseFileInterface):
468
"""List file interface for space-separated values."""
469
470
class IntegerListFile(ListFile):
471
"""Integer list file interface."""
472
473
class CommaDashSetFile(BaseFileInterface):
474
"""Set file interface for comma-dash ranges (e.g., '0-2,4,7-9')."""
475
476
class MultiLineIntegerFile(BaseFileInterface):
477
"""Multi-line integer file interface (one integer per line)."""
478
479
class TypedFile(BaseFileInterface):
480
"""Content type file interface for complex data structures."""
481
482
# Content type classes for specialized data
483
class DeviceAccess:
484
"""Device access permissions with type and access flags."""
485
TYPE_ALL: str = "all"
486
TYPE_CHAR: str = "c"
487
TYPE_BLOCK: str = "b"
488
ACCESS_READ: int = 1
489
ACCESS_WRITE: int = 2
490
ACCESS_MKNOD: int = 4
491
492
def __init__(self, dev_type=None, major=None, minor=None, access=None): ...
493
@property
494
def can_read(self) -> bool: ...
495
@property
496
def can_write(self) -> bool: ...
497
@property
498
def can_mknod(self) -> bool: ...
499
@property
500
def access_string(self) -> str: ...
501
502
class DeviceThrottle:
503
"""Device throttling limits for bandwidth/IOPS control."""
504
def __init__(self, limit: int, major=None, minor=None): ...
505
```