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] vardbapi.removeFromContents: update NEEDED (bug 637284)
Date: Mon, 13 Nov 2017 02:24:48
Message-Id: 20171113022426.72742-1-zmedico@gentoo.org
1 When removing files from CONTENTS, also remove the corresponding
2 lines from NEEDED, so that they do not corrupt LinkageMap data
3 for preserve-libs.
4
5 Bug: https://bugs.gentoo.org/637284
6 ---
7 pym/portage/dbapi/vartree.py | 42 ++++++++++++++++++++++++++++++++++++++++--
8 1 file changed, 40 insertions(+), 2 deletions(-)
9
10 diff --git a/pym/portage/dbapi/vartree.py b/pym/portage/dbapi/vartree.py
11 index 04a40b732..b28b1c56c 100644
12 --- a/pym/portage/dbapi/vartree.py
13 +++ b/pym/portage/dbapi/vartree.py
14 @@ -39,6 +39,7 @@ portage.proxy.lazyimport.lazyimport(globals(),
15 'portage.util._xattr:xattr',
16 'portage.util._dyn_libs.PreservedLibsRegistry:PreservedLibsRegistry',
17 'portage.util._dyn_libs.LinkageMapELF:LinkageMapELF@LinkageMap',
18 + 'portage.util._dyn_libs.NeededEntry:NeededEntry',
19 'portage.util._async.SchedulerInterface:SchedulerInterface',
20 'portage.util._eventloop.EventLoop:EventLoop',
21 'portage.util._eventloop.global_event_loop:global_event_loop',
22 @@ -1094,18 +1095,55 @@ class vardbapi(dbapi):
23 removed += 1
24
25 if removed:
26 - self.writeContentsToContentsFile(pkg, new_contents)
27 + # Also remove corresponding NEEDED lines, so that they do
28 + # no corrupt LinkageMap data for preserve-libs.
29 + needed_filename = os.path.join(pkg.dbdir, LinkageMap._needed_aux_key)
30 + new_needed = None
31 + try:
32 + with io.open(_unicode_encode(needed_filename,
33 + encoding=_encodings['fs'], errors='strict'),
34 + mode='r', encoding=_encodings['repo.content'],
35 + errors='replace') as f:
36 + needed_lines = f.readlines()
37 + except IOError as e:
38 + if e.errno not in (errno.ENOENT, errno.ESTALE):
39 + raise
40 + else:
41 + new_needed = []
42 + for l in needed_lines:
43 + l = l.rstrip("\n")
44 + if not l:
45 + continue
46 + try:
47 + entry = NeededEntry.parse(needed_filename, l)
48 + except InvalidData as e:
49 + writemsg_level("\n%s\n\n" % (e,),
50 + level=logging.ERROR, noiselevel=-1)
51 + continue
52
53 - def writeContentsToContentsFile(self, pkg, new_contents):
54 + filename = os.path.join(root, entry.filename.lstrip(os.sep))
55 + if filename in new_contents:
56 + new_needed.append(entry)
57 +
58 + self.writeContentsToContentsFile(pkg, new_contents, new_needed=new_needed)
59 +
60 + def writeContentsToContentsFile(self, pkg, new_contents, new_needed=None):
61 """
62 @param pkg: package to write contents file for
63 @type pkg: dblink
64 @param new_contents: contents to write to CONTENTS file
65 @type new_contents: contents dictionary of the form
66 {u'/path/to/file' : (contents_attribute 1, ...), ...}
67 + @param new_needed: new NEEDED entries
68 + @type new_needed: list of NeededEntry
69 """
70 root = self.settings['ROOT']
71 self._bump_mtime(pkg.mycpv)
72 + if new_needed is not None:
73 + f = atomic_ofstream(os.path.join(pkg.dbdir, LinkageMap._needed_aux_key))
74 + for entry in new_needed:
75 + f.write(_unicode(entry))
76 + f.close()
77 f = atomic_ofstream(os.path.join(pkg.dbdir, "CONTENTS"))
78 write_contents(new_contents, root, f)
79 f.close()
80 --
81 2.13.5