1 |
For parallel-install, lock when interacting with blocked packages, in |
2 |
order to account for blocked packages being removed or replaced |
3 |
concurrently. |
4 |
|
5 |
X-Gentoo-Bug: 576888 |
6 |
X-Gentoo-Bug-url: https://bugs.gentoo.org/show_bug.cgi?id=576888 |
7 |
--- |
8 |
pym/portage/dbapi/vartree.py | 45 ++++++++++++++++++++++++++++++++++---------- |
9 |
1 file changed, 35 insertions(+), 10 deletions(-) |
10 |
|
11 |
diff --git a/pym/portage/dbapi/vartree.py b/pym/portage/dbapi/vartree.py |
12 |
index e7effca..6d4514c 100644 |
13 |
--- a/pym/portage/dbapi/vartree.py |
14 |
+++ b/pym/portage/dbapi/vartree.py |
15 |
@@ -3932,9 +3932,25 @@ class dblink(object): |
16 |
blockers = self._blockers |
17 |
if blockers is None: |
18 |
blockers = [] |
19 |
- collisions, dirs_ro, symlink_collisions, plib_collisions = \ |
20 |
- self._collision_protect(srcroot, destroot, |
21 |
- others_in_slot + blockers, filelist, linklist) |
22 |
+ |
23 |
+ # For parallel-install, acquire a lock to interact |
24 |
+ # with blocked packages. |
25 |
+ with_lock = bool(blockers) and "parallel-install" in self.settings.features |
26 |
+ |
27 |
+ if with_lock: |
28 |
+ self.lockdb() |
29 |
+ self.vartree.dbapi._fs_lock() |
30 |
+ # Filter out any blocked packages that may have |
31 |
+ # been uninstalled concurrently. |
32 |
+ blockers = [blocker for blocker in blockers if blocker.exists()] |
33 |
+ try: |
34 |
+ collisions, dirs_ro, symlink_collisions, plib_collisions = \ |
35 |
+ self._collision_protect(srcroot, destroot, |
36 |
+ others_in_slot + blockers, filelist, linklist) |
37 |
+ finally: |
38 |
+ if with_lock: |
39 |
+ self.vartree.dbapi._fs_unlock() |
40 |
+ self.unlockdb() |
41 |
|
42 |
# Check for read-only filesystems. |
43 |
ro_checker = get_ro_checker() |
44 |
@@ -4290,13 +4306,22 @@ class dblink(object): |
45 |
self._clear_contents_cache() |
46 |
contents = self.getcontents() |
47 |
destroot_len = len(destroot) - 1 |
48 |
- self.lockdb() |
49 |
- try: |
50 |
- for blocker in blockers: |
51 |
- self.vartree.dbapi.removeFromContents(blocker, iter(contents), |
52 |
- relative_paths=False) |
53 |
- finally: |
54 |
- self.unlockdb() |
55 |
+ |
56 |
+ if blockers: |
57 |
+ self.lockdb() |
58 |
+ self.vartree.dbapi._fs_lock() |
59 |
+ try: |
60 |
+ for blocker in blockers: |
61 |
+ # Blocked packages may have been removed |
62 |
+ # or replaced concurrently, so check if |
63 |
+ # they still exist, and clear contents cache. |
64 |
+ if blocker.exists(): |
65 |
+ blocker._clear_contents_cache() |
66 |
+ self.vartree.dbapi.removeFromContents(blocker, |
67 |
+ iter(contents), relative_paths=False) |
68 |
+ finally: |
69 |
+ self.vartree.dbapi._fs_unlock() |
70 |
+ self.unlockdb() |
71 |
|
72 |
plib_registry = self.vartree.dbapi._plib_registry |
73 |
if plib_registry: |
74 |
-- |
75 |
2.4.10 |