1 |
commit: 9221e327aecfd8585cbb9796add9224123d1c53a |
2 |
Author: Matt Turner <mattst88 <AT> gentoo <DOT> org> |
3 |
AuthorDate: Wed Jun 9 06:17:31 2021 +0000 |
4 |
Commit: Matt Turner <mattst88 <AT> gentoo <DOT> org> |
5 |
CommitDate: Fri Jun 11 04:10:12 2021 +0000 |
6 |
URL: https://gitweb.gentoo.org/proj/catalyst.git/commit/?id=9221e327 |
7 |
|
8 |
catalyst: Replace snakeoil's locks with fasteners |
9 |
|
10 |
To no great surprise, the existing locking was broken. For example, |
11 |
clear_chroot() releases the lock. It is called by unpack(), which is |
12 |
part of prepare_sequence. The result is that the whole build could be |
13 |
done without holding the lock. |
14 |
|
15 |
Just lock around run(). It's not apparent that finer-grained locking |
16 |
does anything for us. |
17 |
|
18 |
For the catalyst-3.0-stable branch, just remove all the snapcache |
19 |
locking. It's broken (bug #519656) and no one is going to fix it, since |
20 |
snapcache has been removed from the master branch. |
21 |
|
22 |
Bug: https://bugs.gentoo.org/791583 |
23 |
Closes: https://bugs.gentoo.org/519656 |
24 |
Signed-off-by: Matt Turner <mattst88 <AT> gentoo.org> |
25 |
(cherry picked from commit b3c917f7fa73d11c69b7e55dc7a00bc18a18edc7) |
26 |
|
27 |
catalyst/base/clearbase.py | 2 -- |
28 |
catalyst/base/stagebase.py | 26 +++++--------------------- |
29 |
catalyst/lock.py | 31 ------------------------------- |
30 |
3 files changed, 5 insertions(+), 54 deletions(-) |
31 |
|
32 |
diff --git a/catalyst/base/clearbase.py b/catalyst/base/clearbase.py |
33 |
index 644a385f..388b1225 100644 |
34 |
--- a/catalyst/base/clearbase.py |
35 |
+++ b/catalyst/base/clearbase.py |
36 |
@@ -28,13 +28,11 @@ class ClearBase(object): |
37 |
|
38 |
|
39 |
def clear_chroot(self): |
40 |
- self.chroot_lock.unlock() |
41 |
log.notice('Clearing the chroot path ...') |
42 |
clear_dir(self.settings["chroot_path"], mode=0o755, chg_flags=True) |
43 |
|
44 |
|
45 |
def remove_chroot(self): |
46 |
- self.chroot_lock.unlock() |
47 |
log.notice('Removing the chroot path ...') |
48 |
clear_dir(self.settings["chroot_path"], mode=0o755, chg_flags=True, remove=True) |
49 |
|
50 |
|
51 |
diff --git a/catalyst/base/stagebase.py b/catalyst/base/stagebase.py |
52 |
index 770d1b35..ad0028e1 100644 |
53 |
--- a/catalyst/base/stagebase.py |
54 |
+++ b/catalyst/base/stagebase.py |
55 |
@@ -4,6 +4,8 @@ import imp |
56 |
import shutil |
57 |
import sys |
58 |
|
59 |
+import fasteners |
60 |
+ |
61 |
from snakeoil import fileutils |
62 |
|
63 |
from DeComp.compress import CompressMap |
64 |
@@ -16,7 +18,6 @@ from catalyst.support import (CatalystError, file_locate, normpath, |
65 |
from catalyst.base.targetbase import TargetBase |
66 |
from catalyst.base.clearbase import ClearBase |
67 |
from catalyst.base.genbase import GenBase |
68 |
-from catalyst.lock import LockDir, LockInUse |
69 |
from catalyst.fileops import ensure_dirs, pjoin, clear_dir, clear_path |
70 |
from catalyst.base.resume import AutoResume |
71 |
|
72 |
@@ -496,8 +497,6 @@ class StageBase(TargetBase, ClearBase, GenBase): |
73 |
self.settings["snapshot_cache_path"] = \ |
74 |
normpath(pjoin(self.settings["snapshot_cache"], |
75 |
self.settings["snapshot"])) |
76 |
- self.snapcache_lock = \ |
77 |
- LockDir(self.settings["snapshot_cache_path"]) |
78 |
log.info('Setting snapshot cache to %s', self.settings['snapshot_cache_path']) |
79 |
|
80 |
def set_chroot_path(self): |
81 |
@@ -507,7 +506,6 @@ class StageBase(TargetBase, ClearBase, GenBase): |
82 |
""" |
83 |
self.settings["chroot_path"] = normpath(self.settings["storedir"] + |
84 |
"/tmp/" + self.settings["target_subpath"].rstrip('/')) |
85 |
- self.chroot_lock = LockDir(self.settings["chroot_path"]) |
86 |
|
87 |
def set_autoresume_path(self): |
88 |
self.settings["autoresume_path"] = normpath(pjoin( |
89 |
@@ -881,8 +879,6 @@ class StageBase(TargetBase, ClearBase, GenBase): |
90 |
unpack = False |
91 |
|
92 |
if unpack: |
93 |
- if "snapcache" in self.settings["options"]: |
94 |
- self.snapcache_lock.write_lock() |
95 |
if os.path.exists(target_portdir): |
96 |
log.info('%s', cleanup_msg) |
97 |
clear_dir(target_portdir) |
98 |
@@ -899,9 +895,6 @@ class StageBase(TargetBase, ClearBase, GenBase): |
99 |
self.resume.enable("unpack_repo", |
100 |
data = self.settings["snapshot_path_hash"]) |
101 |
|
102 |
- if "snapcache" in self.settings["options"]: |
103 |
- self.snapcache_lock.unlock() |
104 |
- |
105 |
def config_profile_link(self): |
106 |
if "autoresume" in self.settings["options"] \ |
107 |
and self.resume.is_enabled("config_profile_link"): |
108 |
@@ -971,8 +964,6 @@ class StageBase(TargetBase, ClearBase, GenBase): |
109 |
|
110 |
src = self.mountmap[x] |
111 |
log.debug('bind(); src = %s', src) |
112 |
- if "snapcache" in self.settings["options"] and x == "portdir": |
113 |
- self.snapcache_lock.read_lock() |
114 |
_cmd = None |
115 |
if src == "maybe_tmpfs": |
116 |
if "var_tmpfs_portage" in self.settings: |
117 |
@@ -1026,15 +1017,6 @@ class StageBase(TargetBase, ClearBase, GenBase): |
118 |
except CatalystError: |
119 |
ouch = 1 |
120 |
log.warning("Couldn't umount bind mount: %s", target) |
121 |
- |
122 |
- if "snapcache" in self.settings["options"] and x == "/var/db/repos/gentoo": |
123 |
- try: |
124 |
- # It's possible the snapshot lock object isn't created yet. |
125 |
- # This is because mount safety check calls unbind before the |
126 |
- # target is fully initialized |
127 |
- self.snapcache_lock.unlock() |
128 |
- except Exception: |
129 |
- pass |
130 |
if ouch: |
131 |
# if any bind mounts really failed, then we need to raise |
132 |
# this to potentially prevent an upcoming bash stage cleanup script |
133 |
@@ -1484,8 +1466,10 @@ class StageBase(TargetBase, ClearBase, GenBase): |
134 |
log.debug('setup_environment(); env = %r', self.env) |
135 |
|
136 |
def run(self): |
137 |
- self.chroot_lock.write_lock() |
138 |
+ with fasteners.InterProcessLock(self.settings["chroot_path"] + '.lock'): |
139 |
+ return self._run() |
140 |
|
141 |
+ def _run(self): |
142 |
# Kill any pids in the chroot |
143 |
self.kill_chroot_pids() |
144 |
|
145 |
|
146 |
diff --git a/catalyst/lock.py b/catalyst/lock.py |
147 |
deleted file mode 100644 |
148 |
index 808df4ec..00000000 |
149 |
--- a/catalyst/lock.py |
150 |
+++ /dev/null |
151 |
@@ -1,31 +0,0 @@ |
152 |
- |
153 |
-import os |
154 |
- |
155 |
-from snakeoil import fileutils |
156 |
-from snakeoil import osutils |
157 |
-from catalyst.fileops import ensure_dirs |
158 |
- |
159 |
- |
160 |
-LockInUse = osutils.LockException |
161 |
- |
162 |
- |
163 |
-class LockDir(object): |
164 |
- """An object that creates locks inside dirs""" |
165 |
- |
166 |
- def __init__(self, lockdir): |
167 |
- self.gid = 250 |
168 |
- self.lockfile = os.path.join(lockdir, '.catalyst_lock') |
169 |
- ensure_dirs(lockdir) |
170 |
- fileutils.touch(self.lockfile, mode=0o664) |
171 |
- os.chown(self.lockfile, -1, self.gid) |
172 |
- self.lock = osutils.FsLock(self.lockfile) |
173 |
- |
174 |
- def read_lock(self): |
175 |
- self.lock.acquire_read_lock() |
176 |
- |
177 |
- def write_lock(self): |
178 |
- self.lock.acquire_write_lock() |
179 |
- |
180 |
- def unlock(self): |
181 |
- # Releasing a write lock is the same as a read lock. |
182 |
- self.lock.release_write_lock() |