1 |
commit: 40f45506b5971073c8a60f172c3171eaf9cad3a6 |
2 |
Author: Zac Medico <zmedico <AT> gentoo <DOT> org> |
3 |
AuthorDate: Mon Aug 1 12:32:00 2011 +0000 |
4 |
Commit: Zac Medico <zmedico <AT> gentoo <DOT> org> |
5 |
CommitDate: Mon Aug 1 12:32:00 2011 +0000 |
6 |
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/portage.git;a=commit;h=40f45506 |
7 |
|
8 |
unmerge: unmerge symlinks broken by rmdir |
9 |
|
10 |
This prevents some more false alarms from commit |
11 |
4bb08136f073024c5d31dceb1618b6f4e7246369. |
12 |
|
13 |
--- |
14 |
pym/portage/dbapi/vartree.py | 36 +++++++++++++++++++++++++++++------- |
15 |
1 files changed, 29 insertions(+), 7 deletions(-) |
16 |
|
17 |
diff --git a/pym/portage/dbapi/vartree.py b/pym/portage/dbapi/vartree.py |
18 |
index 6317af7..58584d7 100644 |
19 |
--- a/pym/portage/dbapi/vartree.py |
20 |
+++ b/pym/portage/dbapi/vartree.py |
21 |
@@ -1909,7 +1909,7 @@ class dblink(object): |
22 |
|
23 |
cfgfiledict = grabdict(self.vartree.dbapi._conf_mem_file) |
24 |
stale_confmem = [] |
25 |
- protected_symlinks = [] |
26 |
+ protected_symlinks = {} |
27 |
|
28 |
unmerge_orphans = "unmerge-orphans" in self.settings.features |
29 |
calc_prelink = "prelink-checksums" in self.settings.features |
30 |
@@ -2054,7 +2054,9 @@ class dblink(object): |
31 |
break |
32 |
|
33 |
if symlink_orphan: |
34 |
- protected_symlinks.append(relative_path) |
35 |
+ protected_symlinks.setdefault( |
36 |
+ (statobj.st_dev, statobj.st_ino), |
37 |
+ []).append(relative_path) |
38 |
|
39 |
if is_owned: |
40 |
show_unmerge("---", unmerge_desc["replaced"], file_type, obj) |
41 |
@@ -2098,7 +2100,7 @@ class dblink(object): |
42 |
if lstatobj is None or not stat.S_ISDIR(lstatobj.st_mode): |
43 |
show_unmerge("---", unmerge_desc["!dir"], file_type, obj) |
44 |
continue |
45 |
- mydirs.add(obj) |
46 |
+ mydirs.add((obj, (lstatobj.st_dev, lstatobj.st_ino))) |
47 |
elif pkgfiles[objkey][0] == "sym": |
48 |
if not islink: |
49 |
show_unmerge("---", unmerge_desc["!sym"], file_type, obj) |
50 |
@@ -2144,7 +2146,9 @@ class dblink(object): |
51 |
break |
52 |
|
53 |
if not all_owned: |
54 |
- protected_symlinks.append(relative_path) |
55 |
+ protected_symlinks.setdefault( |
56 |
+ (statobj.st_dev, statobj.st_ino), |
57 |
+ []).append(relative_path) |
58 |
show_unmerge("---", unmerge_desc["!empty"], |
59 |
file_type, obj) |
60 |
continue |
61 |
@@ -2199,7 +2203,7 @@ class dblink(object): |
62 |
mydirs = sorted(mydirs) |
63 |
mydirs.reverse() |
64 |
|
65 |
- for obj in mydirs: |
66 |
+ for obj, inode_key in mydirs: |
67 |
try: |
68 |
if bsd_chflags: |
69 |
lstatobj = os.lstat(obj) |
70 |
@@ -2224,6 +2228,22 @@ class dblink(object): |
71 |
if e.errno != errno.ENOENT: |
72 |
show_unmerge("---", unmerge_desc["!empty"], "dir", obj) |
73 |
del e |
74 |
+ else: |
75 |
+ # When a directory is successfully removed, there's |
76 |
+ # no need to protect symlinks that point to it. |
77 |
+ unmerge_syms = protected_symlinks.pop(inode_key, None) |
78 |
+ if unmerge_syms is not None: |
79 |
+ for relative_path in unmerge_syms: |
80 |
+ obj = os.path.join(real_root, |
81 |
+ relative_path.lstrip(os.sep)) |
82 |
+ try: |
83 |
+ unlink(obj, os.lstat(obj)) |
84 |
+ show_unmerge("<<<", "", "sym", obj) |
85 |
+ except (OSError, IOError) as e: |
86 |
+ if e.errno not in ignored_unlink_errnos: |
87 |
+ raise |
88 |
+ del e |
89 |
+ show_unmerge("!!!", "", "sym", obj) |
90 |
|
91 |
if protected_symlinks: |
92 |
msg = "One or more symlinks to directories have been " + \ |
93 |
@@ -2231,8 +2251,10 @@ class dblink(object): |
94 |
"via these symlinks remain accessible:" |
95 |
lines = textwrap.wrap(msg, 72) |
96 |
lines.append("") |
97 |
- protected_symlinks.reverse() |
98 |
- for f in protected_symlinks: |
99 |
+ flat_list = set() |
100 |
+ flat_list.update(*protected_symlinks.values()) |
101 |
+ flat_list = sorted(flat_list, reverse=True) |
102 |
+ for f in flat_list: |
103 |
lines.append("\t%s" % (os.path.join(real_root, |
104 |
f.lstrip(os.sep)))) |
105 |
lines.append("") |