1 |
When removal of a symlink is triggered by removal of the directory |
2 |
that it points to, revisit the parent directories of the symlink. |
3 |
|
4 |
Bug: https://bugs.gentoo.org/640058 |
5 |
--- |
6 |
pym/portage/dbapi/vartree.py | 23 +++++++++++++++++++++-- |
7 |
1 file changed, 21 insertions(+), 2 deletions(-) |
8 |
|
9 |
diff --git a/pym/portage/dbapi/vartree.py b/pym/portage/dbapi/vartree.py |
10 |
index 1a86940f1..43e3c4f1a 100644 |
11 |
--- a/pym/portage/dbapi/vartree.py |
12 |
+++ b/pym/portage/dbapi/vartree.py |
13 |
@@ -2753,9 +2753,13 @@ class dblink(object): |
14 |
real_root = self.settings['ROOT'] |
15 |
|
16 |
dirs = sorted(dirs) |
17 |
- dirs.reverse() |
18 |
+ revisit = {} |
19 |
|
20 |
- for obj, inode_key in dirs: |
21 |
+ while True: |
22 |
+ try: |
23 |
+ obj, inode_key = dirs.pop() |
24 |
+ except IndexError: |
25 |
+ break |
26 |
# Treat any directory named "info" as a candidate here, |
27 |
# since it might have been in INFOPATH previously even |
28 |
# though it may not be there now. |
29 |
@@ -2818,6 +2822,7 @@ class dblink(object): |
30 |
raise |
31 |
if e.errno != errno.ENOENT: |
32 |
show_unmerge("---", unmerge_desc["!empty"], "dir", obj) |
33 |
+ revisit[obj] = inode_key |
34 |
|
35 |
# Since we didn't remove this directory, record the directory |
36 |
# itself for use in syncfs calls, if we have removed another |
37 |
@@ -2838,6 +2843,7 @@ class dblink(object): |
38 |
# no need to protect symlinks that point to it. |
39 |
unmerge_syms = protected_symlinks.pop(inode_key, None) |
40 |
if unmerge_syms is not None: |
41 |
+ parents = [] |
42 |
for relative_path in unmerge_syms: |
43 |
obj = os.path.join(real_root, |
44 |
relative_path.lstrip(os.sep)) |
45 |
@@ -2849,6 +2855,19 @@ class dblink(object): |
46 |
raise |
47 |
del e |
48 |
show_unmerge("!!!", "", "sym", obj) |
49 |
+ else: |
50 |
+ parents.append(os.path.dirname(obj)) |
51 |
+ |
52 |
+ if parents: |
53 |
+ # Revisit parents recursively (bug 640058). |
54 |
+ recursive_parents = [] |
55 |
+ for parent in set(parents): |
56 |
+ while parent in revisit: |
57 |
+ recursive_parents.append(parent) |
58 |
+ parent = os.path.dirname(parent) |
59 |
+ |
60 |
+ for parent in sorted(set(recursive_parents)): |
61 |
+ dirs.append((parent, revisit.pop(parent))) |
62 |
|
63 |
def isowner(self, filename, destroot=None): |
64 |
""" |
65 |
-- |
66 |
2.13.6 |