Gentoo Archives: gentoo-portage-dev

From: Zac Medico <zmedico@g.o>
To: gentoo-portage-dev@l.g.o
Cc: Zac Medico <zmedico@g.o>
Subject: [gentoo-portage-dev] [PATCH] _unmerge_dirs: revisit parents of removed symlinks (bug 640058)
Date: Fri, 13 Jul 2018 04:10:02
Message-Id: 20180713040946.18725-1-zmedico@gentoo.org
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

Replies