[Yum-devel] [PATCH] Fix _remove_old_deps to deal with chains of revdeps.

Casey Jao cjao at ugcs.caltech.edu
Fri Apr 8 16:35:55 UTC 2011


Hi,

I've done some minimal testing in a FC14 virtual machine. I installed
emacs, texworks, and google-chrome-stable. Emacs and
google-chrome-stable pulled in some common dependencies, like perl. Then
I did yum remove X where X varied over all subsets of {emacs, texworks,
google-chrome-stable}. In each case yum appeared to correctly resolve
which packages to remove.

What is the preferred method for debug loggin?

Casey




On 04/08/2011 08:56 AM, seth vidal wrote:
> On Fri, 2011-04-08 at 08:44 -0700, Casey Jao wrote:
>> ---
>>  yum/__init__.py |   69
>> +++++++++++++++++++++++++++++++++++++++++++++++++++----
>>  1 files changed, 64 insertions(+), 5 deletions(-)
>>
>> diff --git a/yum/__init__.py b/yum/__init__.py
>> index cf4d827..bbb5204 100644
>> --- a/yum/__init__.py
>> +++ b/yum/__init__.py
>> @@ -5276,6 +5276,11 @@ class YumBase(depsolve.Depsolve):
>>          found_leaves = set()
>>          checked = set()
>>          beingremoved = [ t.po for t in
>> self.tsInfo.getMembersWithState(output_states=TS_REMOVE_STATES) ]
>> +        # cache previously examined packages
>> +        okay_to_remove = {}
>> +        for i in self.rpmdb.returnPackages():
>> +            okay_to_remove[i] = True
>> +
>>          for pkg in beingremoved: # for each package required by the pkg
>> being removed
>>              #print 'removal: %s' % pkg.name
>>              for required in pkg.required_packages():
>> @@ -5283,23 +5288,29 @@ class YumBase(depsolve.Depsolve):
>>                  #    continue # if we've already checked it, skip it.
>>                  #checked.add(required)
>>                  if required.yumdb_info.get('reason', '') != 'dep': # if
>> the required pkg is not a dep, then skip it
>> +                    okay_to_remove[required] = False
>>                      continue
>>                  if required in beingremoved:
>>                      continue
>> +                if self._has_needed_revdeps(required, beingremoved,
>> okay_to_remove):
>> +                    continue
>>                  still_needed = False
>>                  for requiring in required.requiring_packages(): # so we
>> have required deps - look at all the pkgs which require them
>>                      if requiring == required: # if they are
>> self-requiring skip them
>>                          continue
>> -                    if requiring not in beingremoved: # if the
>> requiring pkg is not in the list of pkgs being removed then it is still
>> needed
>> -                        still_needed = True
>> -                        break
>> +                    #if requiring not in beingremoved: # if the
>> requiring pkg is not in the list of pkgs being removed then it is still
>> needed
>> +                        #still_needed = True
>> +                        #break
>> +
>>                  # go through the stuff in the ts to be installed - make
>> sure none of that needs the required pkg, either.
>>                  for (provn,provf,provevr) in required.provides:
>>                      if self.tsInfo.getNewRequires(provn, provf,
>> provevr).keys():
>>                          still_needed = True
>> +                        okay_to_remove[required] = False
>>                          break
>>                  for fn in required.filelist + required.dirlist:
>>                      if self.tsInfo.getNewRequires(fn,
>> None,(None,None,None)).keys():
>> +                        okay_to_remove[required] = False
>>                          still_needed = True
>>                          break
>>
>> @@ -5319,5 +5330,53 @@ class YumBase(depsolve.Depsolve):
>>                              beingremoved.append(txmbr.po)
>>                          found_leaves.add(txmbr)
>>          self.verbose_logger.log(logginglevels.INFO_2, "Found and
>> removing %s unneeded dependencies" % len(found_leaves))
>> -
>> -
>> +
>> +    # Checks if pkg has any reverse deps which cannot be removed.
>> +    # Currently this only checks the install reason for each revdep,
>> +    # but we may want to check for other reasons that would
>> +    # prevent the revdep from being removed (e.g. protected)
>> +    def _has_needed_revdeps(self, pkg, beingremoved, ok_to_remove):
>> +        # check if we've already found this package to have
>> user-installed deps
>> +        if not ok_to_remove[pkg]:
>> +            # Debugging output
>> +            #print pkg, "has been visited already and cannot be removed!!!"
>> +            return True
>> +        # Debugging output
>> +        #print "Examining revdeps of", pkg
>> +        # track which pkgs we have visited already
>> +        visited = {}
>> +        for po in self.rpmdb.returnPackages():
>> +            visited[po] = False
>> +        # no need to consider packages that are already being removed
>> +        for po in beingremoved:
>> +            visited[po] = True
>> +        stack = []
>> +        stack.append(pkg)
>> +        # depth-first search
>> +        while stack:
>> +            curpkg = stack[-1]
>> +            if not visited[curpkg]:
>> +                if not ok_to_remove[curpkg]:
>> +                    # Debugging
>> +                    #print pkg, "has been visited already and cannot be
>> removed!!!"
>> +                    ok_to_remove[pkg] = False
>> +                    return True
>> +                if curpkg.yumdb_info.get('reason', '') != 'dep':
>> +                    # Debugging output
>> +                    #print pkg, "has revdep", curpkg, "which was
>> user-installed."
>> +                    ok_to_remove[pkg] = False
>> +                    return True
>> +                visited[curpkg] = True
>> +            all_leaves_visited = True
>> +            leaves = curpkg.requiring_packages()
>> +            for leaf in leaves:
>> +                if not visited[leaf]:
>> +                    stack.append(leaf)
>> +                    all_leaves_visited = False
>> +                    break
>> +            if all_leaves_visited:
>> +                stack.pop()
>> +        # Debugging output
>> +        #print pkg, "has no user-installed revdeps"
>> +        return False
>> +
>> _______________________________________________
>> Yum-devel mailing list
>> Yum-devel at lists.baseurl.org
>> http://lists.baseurl.org/mailman/listinfo/yum-devel
> 
> 
> Casey,
>  This looks pretty good. Can you clean up the debugging comments and
> maybe turn them into higher debug-level log calls? Also do you have any
> testcases to go along with this?
> 
> Thanks,
> -sv
> 
> 
> _______________________________________________
> Yum-devel mailing list
> Yum-devel at lists.baseurl.org
> http://lists.baseurl.org/mailman/listinfo/yum-devel

-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 553 bytes
Desc: OpenPGP digital signature
URL: <http://lists.baseurl.org/pipermail/yum-devel/attachments/20110408/04ff7892/attachment.asc>


More information about the Yum-devel mailing list