]>
Commit | Line | Data |
---|---|---|
eac44f69 MT |
1 | From 904c8f1136b683a90a08cd4cf671a26f24e45f03 Mon Sep 17 00:00:00 2001 |
2 | From: Michael Tremer <michael.tremer@ipfire.org> | |
3 | Date: Fri, 8 Mar 2013 16:08:16 +0100 | |
4 | Subject: [PATCH 05/19] builder: Use cgroups if the system supports it. | |
5 | ||
6 | A systemd-based system is required right now. | |
7 | --- | |
8 | python/pakfire/builder.py | 12 ++++++-- | |
9 | python/pakfire/cgroup.py | 73 ++++++++++++++++++++++++++++------------------- | |
10 | 2 files changed, 52 insertions(+), 33 deletions(-) | |
11 | ||
12 | diff --git a/python/pakfire/builder.py b/python/pakfire/builder.py | |
13 | index 5cb00aa..7427a8c 100644 | |
14 | --- a/python/pakfire/builder.py | |
15 | +++ b/python/pakfire/builder.py | |
16 | @@ -309,10 +309,16 @@ class BuildEnviron(object): | |
17 | self.cgroup = None | |
18 | return | |
19 | ||
20 | - self.cgroup = cgroup.CGroup("pakfire/builder/%s" % self.build_id) | |
21 | + # Search for the cgroup this process is currently running in. | |
22 | + parent_cgroup = cgroup.find_by_pid(os.getpid()) | |
23 | + if not parent_cgroup: | |
24 | + return | |
25 | + | |
26 | + # Create our own cgroup inside the parent cgroup. | |
27 | + self.cgroup = parent_cgroup.create_child_cgroup("pakfire/builder/%s" % self.build_id) | |
28 | ||
29 | - # Attach the pakfire-builder process to the parent group. | |
30 | - self.cgroup.parent.attach() | |
31 | + # Attach the pakfire-builder process to the group. | |
32 | + self.cgroup.attach() | |
33 | ||
34 | def init_logging(self, logfile): | |
35 | if logfile: | |
36 | diff --git a/python/pakfire/cgroup.py b/python/pakfire/cgroup.py | |
37 | index f372a6c..6c85937 100644 | |
38 | --- a/python/pakfire/cgroup.py | |
39 | +++ b/python/pakfire/cgroup.py | |
40 | @@ -8,40 +8,14 @@ import time | |
41 | import logging | |
42 | log = logging.getLogger("pakfire.cgroups") | |
43 | ||
44 | -CGROUP_PATH_CANDIDATES = ( | |
45 | - "/sys/fs/cgroup", | |
46 | -) | |
47 | - | |
48 | -def find_cgroup_path(): | |
49 | - """ | |
50 | - This function tries to find the right place | |
51 | - where to put the cgroups. | |
52 | - """ | |
53 | - for path in CGROUP_PATH_CANDIDATES: | |
54 | - check_path = os.path.join(path, "tasks") | |
55 | - if not os.path.exists(check_path): | |
56 | - continue | |
57 | - | |
58 | - return path | |
59 | - | |
60 | -CGROUP_PATH = find_cgroup_path() | |
61 | - | |
62 | -def supported(): | |
63 | - """ | |
64 | - Returns True or False depending on | |
65 | - whether cgroups are supported or not. | |
66 | - """ | |
67 | - if CGROUP_PATH is None: | |
68 | - return False | |
69 | - | |
70 | - return True | |
71 | +CGROUP_MOUNTPOINT = "/sys/fs/cgroup/systemd" | |
72 | ||
73 | class CGroup(object): | |
74 | def __init__(self, name): | |
75 | assert supported(), "cgroups are not supported by this kernel" | |
76 | ||
77 | self.name = name | |
78 | - self.path = os.path.join(CGROUP_PATH, name) | |
79 | + self.path = os.path.join(CGROUP_MOUNTPOINT, name) | |
80 | self.path = os.path.abspath(self.path) | |
81 | ||
82 | # The parent cgroup. | |
83 | @@ -58,6 +32,31 @@ class CGroup(object): | |
84 | def __cmp__(self, other): | |
85 | return cmp(self.path, other.path) | |
86 | ||
87 | + @classmethod | |
88 | + def find_by_pid(cls, pid): | |
89 | + """ | |
90 | + Returns the cgroup of the process with the given PID. | |
91 | + | |
92 | + If no cgroup can be found, None is returned. | |
93 | + """ | |
94 | + if not cls.supported: | |
95 | + return | |
96 | + | |
97 | + for d, subdirs, files in os.walk(CGROUP_MOUNTPOINT): | |
98 | + if not "tasks" in files: | |
99 | + continue | |
100 | + | |
101 | + cgroup = cls(d) | |
102 | + if pid in cgroup.tasks: | |
103 | + return cgroup | |
104 | + | |
105 | + @staticmethod | |
106 | + def supported(): | |
107 | + """ | |
108 | + Returns true, if this hosts supports cgroups. | |
109 | + """ | |
110 | + return os.path.ismount(CGROUP_MOUNTPOINT) | |
111 | + | |
112 | def create(self): | |
113 | """ | |
114 | Creates the filesystem structure for | |
115 | @@ -69,6 +68,13 @@ class CGroup(object): | |
116 | log.debug("cgroup '%s' has been created." % self.name) | |
117 | os.makedirs(self.path) | |
118 | ||
119 | + def create_child_cgroup(self, name): | |
120 | + """ | |
121 | + Create a child cgroup with name relative to the | |
122 | + parent cgroup. | |
123 | + """ | |
124 | + return self.__class__(os.path.join(self.name, name)) | |
125 | + | |
126 | def attach(self): | |
127 | """ | |
128 | Attaches this task to the cgroup. | |
129 | @@ -152,8 +158,8 @@ class CGroup(object): | |
130 | ||
131 | @property | |
132 | def parent(self): | |
133 | - # Cannot go above CGROUP_PATH. | |
134 | - if self.path == CGROUP_PATH: | |
135 | + # Cannot go above CGROUP_MOUNTPOINT. | |
136 | + if self.path == CGROUP_MOUNTPOINT: | |
137 | return | |
138 | ||
139 | if self._parent is None: | |
140 | @@ -317,3 +323,10 @@ class CGroup(object): | |
141 | time.sleep(0.2) | |
142 | ||
143 | return self.is_empty() | |
144 | + | |
145 | + | |
146 | +# Alias for simple access to check if this host supports cgroups. | |
147 | +supported = CGroup.supported | |
148 | + | |
149 | +# Alias for simple access to find the cgroup of a certain process. | |
150 | +find_by_pid = CGroup.find_by_pid | |
151 | -- | |
152 | 1.8.1.4 | |
153 |