Re: [gentoo-portage-dev] [PATCH] _unmerge_dirs: revisit parents of removed symlinks (bug 640058)

2018-07-14 Thread Zac Medico
On 07/14/2018 08:31 AM, Brian Dolbec wrote:
> On Thu, 12 Jul 2018 21:09:46 -0700
> Zac Medico  wrote:
> 
>> When removal of a symlink is triggered by removal of the directory
>> that it points to, revisit the parent directories of the symlink.
>>
>> Bug: https://bugs.gentoo.org/640058
>> ---
>>  pym/portage/dbapi/vartree.py | 23 +--
>>  1 file changed, 21 insertions(+), 2 deletions(-)
>>
>> diff --git a/pym/portage/dbapi/vartree.py
>> b/pym/portage/dbapi/vartree.py index 1a86940f1..43e3c4f1a 100644
>> --- a/pym/portage/dbapi/vartree.py
>> +++ b/pym/portage/dbapi/vartree.py
>> @@ -2753,9 +2753,13 @@ class dblink(object):
>>  real_root = self.settings['ROOT']
>>  
>>  dirs = sorted(dirs)
>> -dirs.reverse()
>> +revisit = {}
>>  
>> -for obj, inode_key in dirs:
>> +while True:
>> +try:
>> +obj, inode_key = dirs.pop()
>> +except IndexError:
>> +break
>>  # Treat any directory named "info" as a
>> candidate here, # since it might have been in INFOPATH previously even
>>  # though it may not be there now.
>> @@ -2818,6 +2822,7 @@ class dblink(object):
>>  raise
>>  if e.errno != errno.ENOENT:
>>  show_unmerge("---",
>> unmerge_desc["!empty"], "dir", obj)
>> +revisit[obj] = inode_key
>>  
>>  # Since we didn't remove this
>> directory, record the directory # itself for use in syncfs calls, if
>> we have removed another @@ -2838,6 +2843,7 @@ class dblink(object):
>>  # no need to protect symlinks that
>> point to it. unmerge_syms = protected_symlinks.pop(inode_key, None)
>>  if unmerge_syms is not None:
>> +parents = []
>>  for relative_path in
>> unmerge_syms: obj = os.path.join(real_root,
>>  
>> relative_path.lstrip(os.sep))
>> @@ -2849,6 +2855,19 @@ class dblink(object):
>>  raise
>>  del e
>>  show_unmerge("!!!",
>> "", "sym", obj)
>> +else:
>> +
>> parents.append(os.path.dirname(obj)) +
>> +if parents:
>> +# Revisit parents
>> recursively (bug 640058).
>> +recursive_parents =
>> []
>> +for parent in
>> set(parents):
>> +while parent
>> in revisit:
>> +
>> recursive_parents.append(parent)
>> +
>> parent = os.path.dirname(parent) +
>> +for parent in
>> sorted(set(recursive_parents)):
>> +
>> dirs.append((parent, revisit.pop(parent))) 
>>  def isowner(self, filename, destroot=None):
>>  """
> 
> LGTM
> 

Thanks, merged:

https://gitweb.gentoo.org/proj/portage.git/commit/?id=3a25c3fa13d7c62ba8c00d6c7a75eb907d34b568

-- 
Thanks,
Zac



signature.asc
Description: OpenPGP digital signature


Re: [gentoo-portage-dev] [PATCH] _unmerge_dirs: revisit parents of removed symlinks (bug 640058)

2018-07-14 Thread Brian Dolbec
On Thu, 12 Jul 2018 21:09:46 -0700
Zac Medico  wrote:

> When removal of a symlink is triggered by removal of the directory
> that it points to, revisit the parent directories of the symlink.
> 
> Bug: https://bugs.gentoo.org/640058
> ---
>  pym/portage/dbapi/vartree.py | 23 +--
>  1 file changed, 21 insertions(+), 2 deletions(-)
> 
> diff --git a/pym/portage/dbapi/vartree.py
> b/pym/portage/dbapi/vartree.py index 1a86940f1..43e3c4f1a 100644
> --- a/pym/portage/dbapi/vartree.py
> +++ b/pym/portage/dbapi/vartree.py
> @@ -2753,9 +2753,13 @@ class dblink(object):
>   real_root = self.settings['ROOT']
>  
>   dirs = sorted(dirs)
> - dirs.reverse()
> + revisit = {}
>  
> - for obj, inode_key in dirs:
> + while True:
> + try:
> + obj, inode_key = dirs.pop()
> + except IndexError:
> + break
>   # Treat any directory named "info" as a
> candidate here, # since it might have been in INFOPATH previously even
>   # though it may not be there now.
> @@ -2818,6 +2822,7 @@ class dblink(object):
>   raise
>   if e.errno != errno.ENOENT:
>   show_unmerge("---",
> unmerge_desc["!empty"], "dir", obj)
> + revisit[obj] = inode_key
>  
>   # Since we didn't remove this
> directory, record the directory # itself for use in syncfs calls, if
> we have removed another @@ -2838,6 +2843,7 @@ class dblink(object):
>   # no need to protect symlinks that
> point to it. unmerge_syms = protected_symlinks.pop(inode_key, None)
>   if unmerge_syms is not None:
> + parents = []
>   for relative_path in
> unmerge_syms: obj = os.path.join(real_root,
>   
> relative_path.lstrip(os.sep))
> @@ -2849,6 +2855,19 @@ class dblink(object):
>   raise
>   del e
>   show_unmerge("!!!",
> "", "sym", obj)
> + else:
> +
> parents.append(os.path.dirname(obj)) +
> + if parents:
> + # Revisit parents
> recursively (bug 640058).
> + recursive_parents =
> []
> + for parent in
> set(parents):
> + while parent
> in revisit:
> +
> recursive_parents.append(parent)
> +
> parent = os.path.dirname(parent) +
> + for parent in
> sorted(set(recursive_parents)):
> +
> dirs.append((parent, revisit.pop(parent))) 
>   def isowner(self, filename, destroot=None):
>   """

LGTM

-- 
Brian Dolbec 




[gentoo-portage-dev] [PATCH] _unmerge_dirs: revisit parents of removed symlinks (bug 640058)

2018-07-12 Thread Zac Medico
When removal of a symlink is triggered by removal of the directory
that it points to, revisit the parent directories of the symlink.

Bug: https://bugs.gentoo.org/640058
---
 pym/portage/dbapi/vartree.py | 23 +--
 1 file changed, 21 insertions(+), 2 deletions(-)

diff --git a/pym/portage/dbapi/vartree.py b/pym/portage/dbapi/vartree.py
index 1a86940f1..43e3c4f1a 100644
--- a/pym/portage/dbapi/vartree.py
+++ b/pym/portage/dbapi/vartree.py
@@ -2753,9 +2753,13 @@ class dblink(object):
real_root = self.settings['ROOT']
 
dirs = sorted(dirs)
-   dirs.reverse()
+   revisit = {}
 
-   for obj, inode_key in dirs:
+   while True:
+   try:
+   obj, inode_key = dirs.pop()
+   except IndexError:
+   break
# Treat any directory named "info" as a candidate here,
# since it might have been in INFOPATH previously even
# though it may not be there now.
@@ -2818,6 +2822,7 @@ class dblink(object):
raise
if e.errno != errno.ENOENT:
show_unmerge("---", 
unmerge_desc["!empty"], "dir", obj)
+   revisit[obj] = inode_key
 
# Since we didn't remove this directory, record 
the directory
# itself for use in syncfs calls, if we have 
removed another
@@ -2838,6 +2843,7 @@ class dblink(object):
# no need to protect symlinks that point to it.
unmerge_syms = 
protected_symlinks.pop(inode_key, None)
if unmerge_syms is not None:
+   parents = []
for relative_path in unmerge_syms:
obj = os.path.join(real_root,

relative_path.lstrip(os.sep))
@@ -2849,6 +2855,19 @@ class dblink(object):
raise
del e
show_unmerge("!!!", "", 
"sym", obj)
+   else:
+   
parents.append(os.path.dirname(obj))
+
+   if parents:
+   # Revisit parents recursively 
(bug 640058).
+   recursive_parents = []
+   for parent in set(parents):
+   while parent in revisit:
+   
recursive_parents.append(parent)
+   parent = 
os.path.dirname(parent)
+
+   for parent in 
sorted(set(recursive_parents)):
+   dirs.append((parent, 
revisit.pop(parent)))
 
def isowner(self, filename, destroot=None):
"""
-- 
2.13.6