Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
torvalds
GitHub Repository: torvalds/linux
Path: blob/master/tools/testing/selftests/damon/_damon_sysfs.py
29268 views
1
# SPDX-License-Identifier: GPL-2.0
2
3
import os
4
5
ksft_skip=4
6
7
sysfs_root = None
8
with open('/proc/mounts', 'r') as f:
9
for line in f:
10
dev_name, mount_point, dev_fs = line.split()[:3]
11
if dev_fs == 'sysfs':
12
sysfs_root = '%s/kernel/mm/damon/admin' % mount_point
13
break
14
if sysfs_root is None:
15
print('Seems sysfs not mounted?')
16
exit(ksft_skip)
17
18
if not os.path.exists(sysfs_root):
19
print('Seems DAMON disabled?')
20
exit(ksft_skip)
21
22
def write_file(path, string):
23
"Returns error string if failed, or None otherwise"
24
string = '%s' % string
25
try:
26
with open(path, 'w') as f:
27
f.write(string)
28
except Exception as e:
29
return '%s' % e
30
return None
31
32
def read_file(path):
33
'''Returns the read content and error string. The read content is None if
34
the reading failed'''
35
try:
36
with open(path, 'r') as f:
37
return f.read(), None
38
except Exception as e:
39
return None, '%s' % e
40
41
class DamosAccessPattern:
42
size = None
43
nr_accesses = None
44
age = None
45
scheme = None
46
47
def __init__(self, size=None, nr_accesses=None, age=None):
48
self.size = size
49
self.nr_accesses = nr_accesses
50
self.age = age
51
52
if self.size is None:
53
self.size = [0, 2**64 - 1]
54
if self.nr_accesses is None:
55
self.nr_accesses = [0, 2**32 - 1]
56
if self.age is None:
57
self.age = [0, 2**32 - 1]
58
59
def sysfs_dir(self):
60
return os.path.join(self.scheme.sysfs_dir(), 'access_pattern')
61
62
def stage(self):
63
err = write_file(
64
os.path.join(self.sysfs_dir(), 'sz', 'min'), self.size[0])
65
if err is not None:
66
return err
67
err = write_file(
68
os.path.join(self.sysfs_dir(), 'sz', 'max'), self.size[1])
69
if err is not None:
70
return err
71
err = write_file(os.path.join(self.sysfs_dir(), 'nr_accesses', 'min'),
72
self.nr_accesses[0])
73
if err is not None:
74
return err
75
err = write_file(os.path.join(self.sysfs_dir(), 'nr_accesses', 'max'),
76
self.nr_accesses[1])
77
if err is not None:
78
return err
79
err = write_file(
80
os.path.join(self.sysfs_dir(), 'age', 'min'), self.age[0])
81
if err is not None:
82
return err
83
err = write_file(
84
os.path.join(self.sysfs_dir(), 'age', 'max'), self.age[1])
85
if err is not None:
86
return err
87
88
qgoal_metric_user_input = 'user_input'
89
qgoal_metric_some_mem_psi_us = 'some_mem_psi_us'
90
qgoal_metrics = [qgoal_metric_user_input, qgoal_metric_some_mem_psi_us]
91
92
class DamosQuotaGoal:
93
metric = None
94
target_value = None
95
current_value = None
96
nid = None
97
effective_bytes = None
98
quota = None # owner quota
99
idx = None
100
101
def __init__(self, metric, target_value=10000, current_value=0, nid=0):
102
self.metric = metric
103
self.target_value = target_value
104
self.current_value = current_value
105
self.nid = nid
106
107
def sysfs_dir(self):
108
return os.path.join(self.quota.sysfs_dir(), 'goals', '%d' % self.idx)
109
110
def stage(self):
111
err = write_file(os.path.join(self.sysfs_dir(), 'target_metric'),
112
self.metric)
113
if err is not None:
114
return err
115
err = write_file(os.path.join(self.sysfs_dir(), 'target_value'),
116
self.target_value)
117
if err is not None:
118
return err
119
err = write_file(os.path.join(self.sysfs_dir(), 'current_value'),
120
self.current_value)
121
if err is not None:
122
return err
123
err = write_file(os.path.join(self.sysfs_dir(), 'nid'), self.nid)
124
if err is not None:
125
return err
126
127
return None
128
129
class DamosQuota:
130
sz = None # size quota, in bytes
131
ms = None # time quota
132
goals = None # quota goals
133
reset_interval_ms = None # quota reset interval
134
weight_sz_permil = None
135
weight_nr_accesses_permil = None
136
weight_age_permil = None
137
scheme = None # owner scheme
138
139
def __init__(self, sz=0, ms=0, goals=None, reset_interval_ms=0,
140
weight_sz_permil=0, weight_nr_accesses_permil=0,
141
weight_age_permil=0):
142
self.sz = sz
143
self.ms = ms
144
self.reset_interval_ms = reset_interval_ms
145
self.weight_sz_permil = weight_sz_permil
146
self.weight_nr_accesses_permil = weight_nr_accesses_permil
147
self.weight_age_permil = weight_age_permil
148
self.goals = goals if goals is not None else []
149
for idx, goal in enumerate(self.goals):
150
goal.idx = idx
151
goal.quota = self
152
153
def sysfs_dir(self):
154
return os.path.join(self.scheme.sysfs_dir(), 'quotas')
155
156
def stage(self):
157
err = write_file(os.path.join(self.sysfs_dir(), 'bytes'), self.sz)
158
if err is not None:
159
return err
160
err = write_file(os.path.join(self.sysfs_dir(), 'ms'), self.ms)
161
if err is not None:
162
return err
163
err = write_file(os.path.join(self.sysfs_dir(), 'reset_interval_ms'),
164
self.reset_interval_ms)
165
if err is not None:
166
return err
167
168
err = write_file(os.path.join(
169
self.sysfs_dir(), 'weights', 'sz_permil'), self.weight_sz_permil)
170
if err is not None:
171
return err
172
err = write_file(os.path.join(
173
self.sysfs_dir(), 'weights', 'nr_accesses_permil'),
174
self.weight_nr_accesses_permil)
175
if err is not None:
176
return err
177
err = write_file(os.path.join(
178
self.sysfs_dir(), 'weights', 'age_permil'), self.weight_age_permil)
179
if err is not None:
180
return err
181
182
nr_goals_file = os.path.join(self.sysfs_dir(), 'goals', 'nr_goals')
183
content, err = read_file(nr_goals_file)
184
if err is not None:
185
return err
186
if int(content) != len(self.goals):
187
err = write_file(nr_goals_file, len(self.goals))
188
if err is not None:
189
return err
190
for goal in self.goals:
191
err = goal.stage()
192
if err is not None:
193
return err
194
return None
195
196
class DamosWatermarks:
197
metric = None
198
interval = None
199
high = None
200
mid = None
201
low = None
202
scheme = None # owner scheme
203
204
def __init__(self, metric='none', interval=0, high=0, mid=0, low=0):
205
self.metric = metric
206
self.interval = interval
207
self.high = high
208
self.mid = mid
209
self.low = low
210
211
def sysfs_dir(self):
212
return os.path.join(self.scheme.sysfs_dir(), 'watermarks')
213
214
def stage(self):
215
err = write_file(os.path.join(self.sysfs_dir(), 'metric'), self.metric)
216
if err is not None:
217
return err
218
err = write_file(os.path.join(self.sysfs_dir(), 'interval_us'),
219
self.interval)
220
if err is not None:
221
return err
222
err = write_file(os.path.join(self.sysfs_dir(), 'high'), self.high)
223
if err is not None:
224
return err
225
err = write_file(os.path.join(self.sysfs_dir(), 'mid'), self.mid)
226
if err is not None:
227
return err
228
err = write_file(os.path.join(self.sysfs_dir(), 'low'), self.low)
229
if err is not None:
230
return err
231
232
class DamosFilter:
233
type_ = None
234
matching = None
235
allow = None
236
memcg_path = None
237
addr_start = None
238
addr_end = None
239
target_idx = None
240
min_ = None
241
max_ = None
242
idx = None
243
filters = None # owner filters
244
245
def __init__(self, type_='anon', matching=False, allow=False,
246
memcg_path='', addr_start=0, addr_end=0, target_idx=0, min_=0,
247
max_=0):
248
self.type_ = type_
249
self.matching = matching
250
self.allow = allow
251
self.memcg_path = memcg_path,
252
self.addr_start = addr_start
253
self.addr_end = addr_end
254
self.target_idx = target_idx
255
self.min_ = min_
256
self.max_ = max_
257
258
def sysfs_dir(self):
259
return os.path.join(self.filters.sysfs_dir(), '%d' % self.idx)
260
261
def stage(self):
262
err = write_file(os.path.join(self.sysfs_dir(), 'type'), self.type_)
263
if err is not None:
264
return err
265
err = write_file(os.path.join(self.sysfs_dir(), 'matching'),
266
self.matching)
267
if err is not None:
268
return err
269
err = write_file(os.path.join(self.sysfs_dir(), 'allow'), self.allow)
270
if err is not None:
271
return err
272
err = write_file(os.path.join(self.sysfs_dir(), 'memcg_path'),
273
self.memcg_path)
274
if err is not None:
275
return err
276
err = write_file(os.path.join(self.sysfs_dir(), 'addr_start'),
277
self.addr_start)
278
if err is not None:
279
return err
280
err = write_file(os.path.join(self.sysfs_dir(), 'addr_end'),
281
self.addr_end)
282
if err is not None:
283
return err
284
err = write_file(os.path.join(self.sysfs_dir(), 'damon_target_idx'),
285
self.target_idx)
286
if err is not None:
287
return err
288
err = write_file(os.path.join(self.sysfs_dir(), 'min'), self.min_)
289
if err is not None:
290
return err
291
err = write_file(os.path.join(self.sysfs_dir(), 'max'), self.max_)
292
if err is not None:
293
return err
294
return None
295
296
class DamosFilters:
297
name = None
298
filters = None
299
scheme = None # owner scheme
300
301
def __init__(self, name, filters=[]):
302
self.name = name
303
self.filters = filters
304
for idx, filter_ in enumerate(self.filters):
305
filter_.idx = idx
306
filter_.filters = self
307
308
def sysfs_dir(self):
309
return os.path.join(self.scheme.sysfs_dir(), self.name)
310
311
def stage(self):
312
err = write_file(os.path.join(self.sysfs_dir(), 'nr_filters'),
313
len(self.filters))
314
if err is not None:
315
return err
316
for filter_ in self.filters:
317
err = filter_.stage()
318
if err is not None:
319
return err
320
return None
321
322
class DamosDest:
323
id = None
324
weight = None
325
idx = None
326
dests = None # owner dests
327
328
def __init__(self, id=0, weight=0):
329
self.id = id
330
self.weight = weight
331
332
def sysfs_dir(self):
333
return os.path.join(self.dests.sysfs_dir(), '%d' % self.idx)
334
335
def stage(self):
336
err = write_file(os.path.join(self.sysfs_dir(), 'id'), self.id)
337
if err is not None:
338
return err
339
err = write_file(os.path.join(self.sysfs_dir(), 'weight'), self.weight)
340
if err is not None:
341
return err
342
return None
343
344
class DamosDests:
345
dests = None
346
scheme = None # owner scheme
347
348
def __init__(self, dests=[]):
349
self.dests = dests
350
for idx, dest in enumerate(self.dests):
351
dest.idx = idx
352
dest.dests = self
353
354
def sysfs_dir(self):
355
return os.path.join(self.scheme.sysfs_dir(), 'dests')
356
357
def stage(self):
358
err = write_file(os.path.join(self.sysfs_dir(), 'nr_dests'),
359
len(self.dests))
360
if err is not None:
361
return err
362
for dest in self.dests:
363
err = dest.stage()
364
if err is not None:
365
return err
366
return None
367
368
class DamosStats:
369
nr_tried = None
370
sz_tried = None
371
nr_applied = None
372
sz_applied = None
373
qt_exceeds = None
374
375
def __init__(self, nr_tried, sz_tried, nr_applied, sz_applied, qt_exceeds):
376
self.nr_tried = nr_tried
377
self.sz_tried = sz_tried
378
self.nr_applied = nr_applied
379
self.sz_applied = sz_applied
380
self.qt_exceeds = qt_exceeds
381
382
class DamosTriedRegion:
383
def __init__(self, start, end, nr_accesses, age):
384
self.start = start
385
self.end = end
386
self.nr_accesses = nr_accesses
387
self.age = age
388
389
class Damos:
390
action = None
391
access_pattern = None
392
quota = None
393
watermarks = None
394
core_filters = None
395
ops_filters = None
396
filters = None
397
apply_interval_us = None
398
target_nid = None
399
dests = None
400
idx = None
401
context = None
402
tried_bytes = None
403
stats = None
404
tried_regions = None
405
406
def __init__(self, action='stat', access_pattern=DamosAccessPattern(),
407
quota=DamosQuota(), watermarks=DamosWatermarks(),
408
core_filters=[], ops_filters=[], filters=[], target_nid=0,
409
dests=DamosDests(), apply_interval_us=0):
410
self.action = action
411
self.access_pattern = access_pattern
412
self.access_pattern.scheme = self
413
self.quota = quota
414
self.quota.scheme = self
415
self.watermarks = watermarks
416
self.watermarks.scheme = self
417
418
self.core_filters = DamosFilters(name='core_filters',
419
filters=core_filters)
420
self.core_filters.scheme = self
421
self.ops_filters = DamosFilters(name='ops_filters',
422
filters=ops_filters)
423
self.ops_filters.scheme = self
424
self.filters = DamosFilters(name='filters', filters=filters)
425
self.filters.scheme = self
426
427
self.target_nid = target_nid
428
self.dests = dests
429
self.dests.scheme = self
430
431
self.apply_interval_us = apply_interval_us
432
433
def sysfs_dir(self):
434
return os.path.join(
435
self.context.sysfs_dir(), 'schemes', '%d' % self.idx)
436
437
def stage(self):
438
err = write_file(os.path.join(self.sysfs_dir(), 'action'), self.action)
439
if err is not None:
440
return err
441
err = self.access_pattern.stage()
442
if err is not None:
443
return err
444
err = write_file(os.path.join(self.sysfs_dir(), 'apply_interval_us'),
445
'%d' % self.apply_interval_us)
446
if err is not None:
447
return err
448
449
err = self.quota.stage()
450
if err is not None:
451
return err
452
453
err = self.watermarks.stage()
454
if err is not None:
455
return err
456
457
err = self.core_filters.stage()
458
if err is not None:
459
return err
460
err = self.ops_filters.stage()
461
if err is not None:
462
return err
463
err = self.filters.stage()
464
if err is not None:
465
return err
466
467
err = write_file(os.path.join(self.sysfs_dir(), 'target_nid'), '%d' %
468
self.target_nid)
469
if err is not None:
470
return err
471
472
err = self.dests.stage()
473
if err is not None:
474
return err
475
476
class DamonTarget:
477
pid = None
478
# todo: Support target regions if test is made
479
idx = None
480
context = None
481
482
def __init__(self, pid):
483
self.pid = pid
484
485
def sysfs_dir(self):
486
return os.path.join(
487
self.context.sysfs_dir(), 'targets', '%d' % self.idx)
488
489
def stage(self):
490
err = write_file(
491
os.path.join(self.sysfs_dir(), 'regions', 'nr_regions'), '0')
492
if err is not None:
493
return err
494
return write_file(
495
os.path.join(self.sysfs_dir(), 'pid_target'), self.pid)
496
497
class IntervalsGoal:
498
access_bp = None
499
aggrs = None
500
min_sample_us = None
501
max_sample_us = None
502
attrs = None # owner DamonAttrs
503
504
def __init__(self, access_bp=0, aggrs=0, min_sample_us=0, max_sample_us=0):
505
self.access_bp = access_bp
506
self.aggrs = aggrs
507
self.min_sample_us = min_sample_us
508
self.max_sample_us = max_sample_us
509
510
def sysfs_dir(self):
511
return os.path.join(self.attrs.interval_sysfs_dir(), 'intervals_goal')
512
513
def stage(self):
514
err = write_file(
515
os.path.join(self.sysfs_dir(), 'access_bp'), self.access_bp)
516
if err is not None:
517
return err
518
err = write_file(os.path.join(self.sysfs_dir(), 'aggrs'), self.aggrs)
519
if err is not None:
520
return err
521
err = write_file(os.path.join(self.sysfs_dir(), 'min_sample_us'),
522
self.min_sample_us)
523
if err is not None:
524
return err
525
err = write_file(os.path.join(self.sysfs_dir(), 'max_sample_us'),
526
self.max_sample_us)
527
if err is not None:
528
return err
529
return None
530
531
class DamonAttrs:
532
sample_us = None
533
aggr_us = None
534
intervals_goal = None
535
update_us = None
536
min_nr_regions = None
537
max_nr_regions = None
538
context = None
539
540
def __init__(self, sample_us=5000, aggr_us=100000,
541
intervals_goal=IntervalsGoal(), update_us=1000000,
542
min_nr_regions=10, max_nr_regions=1000):
543
self.sample_us = sample_us
544
self.aggr_us = aggr_us
545
self.intervals_goal = intervals_goal
546
self.intervals_goal.attrs = self
547
self.update_us = update_us
548
self.min_nr_regions = min_nr_regions
549
self.max_nr_regions = max_nr_regions
550
551
def interval_sysfs_dir(self):
552
return os.path.join(self.context.sysfs_dir(), 'monitoring_attrs',
553
'intervals')
554
555
def nr_regions_range_sysfs_dir(self):
556
return os.path.join(self.context.sysfs_dir(), 'monitoring_attrs',
557
'nr_regions')
558
559
def stage(self):
560
err = write_file(os.path.join(self.interval_sysfs_dir(), 'sample_us'),
561
self.sample_us)
562
if err is not None:
563
return err
564
err = write_file(os.path.join(self.interval_sysfs_dir(), 'aggr_us'),
565
self.aggr_us)
566
if err is not None:
567
return err
568
err = self.intervals_goal.stage()
569
if err is not None:
570
return err
571
err = write_file(os.path.join(self.interval_sysfs_dir(), 'update_us'),
572
self.update_us)
573
if err is not None:
574
return err
575
576
err = write_file(
577
os.path.join(self.nr_regions_range_sysfs_dir(), 'min'),
578
self.min_nr_regions)
579
if err is not None:
580
return err
581
582
err = write_file(
583
os.path.join(self.nr_regions_range_sysfs_dir(), 'max'),
584
self.max_nr_regions)
585
if err is not None:
586
return err
587
588
class DamonCtx:
589
ops = None
590
monitoring_attrs = None
591
targets = None
592
schemes = None
593
kdamond = None
594
idx = None
595
596
def __init__(self, ops='paddr', monitoring_attrs=DamonAttrs(), targets=[],
597
schemes=[]):
598
self.ops = ops
599
self.monitoring_attrs = monitoring_attrs
600
self.monitoring_attrs.context = self
601
602
self.targets = targets
603
for idx, target in enumerate(self.targets):
604
target.idx = idx
605
target.context = self
606
607
self.schemes = schemes
608
for idx, scheme in enumerate(self.schemes):
609
scheme.idx = idx
610
scheme.context = self
611
612
def sysfs_dir(self):
613
return os.path.join(self.kdamond.sysfs_dir(), 'contexts',
614
'%d' % self.idx)
615
616
def stage(self):
617
err = write_file(
618
os.path.join(self.sysfs_dir(), 'operations'), self.ops)
619
if err is not None:
620
return err
621
err = self.monitoring_attrs.stage()
622
if err is not None:
623
return err
624
625
nr_targets_file = os.path.join(
626
self.sysfs_dir(), 'targets', 'nr_targets')
627
content, err = read_file(nr_targets_file)
628
if err is not None:
629
return err
630
if int(content) != len(self.targets):
631
err = write_file(nr_targets_file, '%d' % len(self.targets))
632
if err is not None:
633
return err
634
for target in self.targets:
635
err = target.stage()
636
if err is not None:
637
return err
638
639
nr_schemes_file = os.path.join(
640
self.sysfs_dir(), 'schemes', 'nr_schemes')
641
content, err = read_file(nr_schemes_file)
642
if err is not None:
643
return err
644
if int(content) != len(self.schemes):
645
err = write_file(nr_schemes_file, '%d' % len(self.schemes))
646
if err is not None:
647
return err
648
for scheme in self.schemes:
649
err = scheme.stage()
650
if err is not None:
651
return err
652
return None
653
654
class Kdamond:
655
state = None
656
pid = None
657
contexts = None
658
idx = None # index of this kdamond between siblings
659
kdamonds = None # parent
660
661
def __init__(self, contexts=[]):
662
self.contexts = contexts
663
for idx, context in enumerate(self.contexts):
664
context.idx = idx
665
context.kdamond = self
666
667
def sysfs_dir(self):
668
return os.path.join(self.kdamonds.sysfs_dir(), '%d' % self.idx)
669
670
def start(self):
671
nr_contexts_file = os.path.join(self.sysfs_dir(),
672
'contexts', 'nr_contexts')
673
content, err = read_file(nr_contexts_file)
674
if err is not None:
675
return err
676
if int(content) != len(self.contexts):
677
err = write_file(nr_contexts_file, '%d' % len(self.contexts))
678
if err is not None:
679
return err
680
681
for context in self.contexts:
682
err = context.stage()
683
if err is not None:
684
return err
685
err = write_file(os.path.join(self.sysfs_dir(), 'state'), 'on')
686
if err is not None:
687
return err
688
self.pid, err = read_file(os.path.join(self.sysfs_dir(), 'pid'))
689
return err
690
691
def stop(self):
692
err = write_file(os.path.join(self.sysfs_dir(), 'state'), 'off')
693
return err
694
695
def update_schemes_tried_regions(self):
696
err = write_file(os.path.join(self.sysfs_dir(), 'state'),
697
'update_schemes_tried_regions')
698
if err is not None:
699
return err
700
for context in self.contexts:
701
for scheme in context.schemes:
702
tried_regions = []
703
tried_regions_dir = os.path.join(
704
scheme.sysfs_dir(), 'tried_regions')
705
region_indices = []
706
for filename in os.listdir(
707
os.path.join(scheme.sysfs_dir(), 'tried_regions')):
708
tried_region_dir = os.path.join(tried_regions_dir, filename)
709
if not os.path.isdir(tried_region_dir):
710
continue
711
region_indices.append(int(filename))
712
for region_idx in sorted(region_indices):
713
tried_region_dir = os.path.join(tried_regions_dir,
714
'%d' % region_idx)
715
region_values = []
716
for f in ['start', 'end', 'nr_accesses', 'age']:
717
content, err = read_file(
718
os.path.join(tried_region_dir, f))
719
if err is not None:
720
return err
721
region_values.append(int(content))
722
tried_regions.append(DamosTriedRegion(*region_values))
723
scheme.tried_regions = tried_regions
724
725
def update_schemes_tried_bytes(self):
726
err = write_file(os.path.join(self.sysfs_dir(), 'state'),
727
'update_schemes_tried_bytes')
728
if err is not None:
729
return err
730
for context in self.contexts:
731
for scheme in context.schemes:
732
content, err = read_file(os.path.join(scheme.sysfs_dir(),
733
'tried_regions', 'total_bytes'))
734
if err is not None:
735
return err
736
scheme.tried_bytes = int(content)
737
738
def update_schemes_stats(self):
739
err = write_file(os.path.join(self.sysfs_dir(), 'state'),
740
'update_schemes_stats')
741
if err is not None:
742
return err
743
for context in self.contexts:
744
for scheme in context.schemes:
745
stat_values = []
746
for stat in ['nr_tried', 'sz_tried', 'nr_applied',
747
'sz_applied', 'qt_exceeds']:
748
content, err = read_file(
749
os.path.join(scheme.sysfs_dir(), 'stats', stat))
750
if err is not None:
751
return err
752
stat_values.append(int(content))
753
scheme.stats = DamosStats(*stat_values)
754
755
def update_schemes_effective_quotas(self):
756
err = write_file(os.path.join(self.sysfs_dir(), 'state'),
757
'update_schemes_effective_quotas')
758
if err is not None:
759
return err
760
for context in self.contexts:
761
for scheme in context.schemes:
762
for goal in scheme.quota.goals:
763
content, err = read_file(
764
os.path.join(scheme.quota.sysfs_dir(),
765
'effective_bytes'))
766
if err is not None:
767
return err
768
goal.effective_bytes = int(content)
769
return None
770
771
def commit(self):
772
nr_contexts_file = os.path.join(self.sysfs_dir(),
773
'contexts', 'nr_contexts')
774
content, err = read_file(nr_contexts_file)
775
if err is not None:
776
return err
777
if int(content) != len(self.contexts):
778
err = write_file(nr_contexts_file, '%d' % len(self.contexts))
779
if err is not None:
780
return err
781
782
for context in self.contexts:
783
err = context.stage()
784
if err is not None:
785
return err
786
err = write_file(os.path.join(self.sysfs_dir(), 'state'), 'commit')
787
return err
788
789
790
def commit_schemes_quota_goals(self):
791
for context in self.contexts:
792
for scheme in context.schemes:
793
for goal in scheme.quota.goals:
794
err = goal.stage()
795
if err is not None:
796
print('commit_schemes_quota_goals failed stagign: %s'%
797
err)
798
exit(1)
799
return write_file(os.path.join(self.sysfs_dir(), 'state'),
800
'commit_schemes_quota_goals')
801
802
class Kdamonds:
803
kdamonds = []
804
805
def __init__(self, kdamonds=[]):
806
self.kdamonds = kdamonds
807
for idx, kdamond in enumerate(self.kdamonds):
808
kdamond.idx = idx
809
kdamond.kdamonds = self
810
811
def sysfs_dir(self):
812
return os.path.join(sysfs_root, 'kdamonds')
813
814
def start(self):
815
err = write_file(os.path.join(self.sysfs_dir(), 'nr_kdamonds'),
816
'%s' % len(self.kdamonds))
817
if err is not None:
818
return err
819
for kdamond in self.kdamonds:
820
err = kdamond.start()
821
if err is not None:
822
return err
823
return None
824
825
def stop(self):
826
for kdamond in self.kdamonds:
827
err = kdamond.stop()
828
if err is not None:
829
return err
830
return None
831
832