[yum/f17] update to latest HEAD

Zdeněk Pavlas zpavlas at fedoraproject.org
Thu Jun 7 15:44:24 UTC 2012


commit 100fd66aa3e36e43d0fcf57e811db2b95b0ba7b5
Author: Zdeněk Pavlas <zpavlas at redhat.com>
Date:   Thu Jun 7 17:42:48 2012 +0200

    update to latest HEAD

 BZ-809469-completion-helper.patch |   76 --
 arm-arch-detection.patch          |  104 --
 yum-HEAD.patch                    | 1896 +++++++++++++++++++++++++++++++------
 yum-ppc64-preferred.patch         |    4 +-
 yum.spec                          |   14 +-
 5 files changed, 1598 insertions(+), 496 deletions(-)
---
diff --git a/yum-HEAD.patch b/yum-HEAD.patch
index 1fa8c87..1d38d0a 100644
--- a/yum-HEAD.patch
+++ b/yum-HEAD.patch
@@ -96,7 +96,7 @@ index 2f6154e..2e5a052 100644
 diff --git a/cli.py b/cli.py
 old mode 100644
 new mode 100755
-index 6056d38..afa7447
+index 6056d38..597efd6
 --- a/cli.py
 +++ b/cli.py
 @@ -25,7 +25,7 @@ import sys
@@ -372,8 +372,22 @@ index 6056d38..afa7447
                  stuff_to_download = True
                  po = txmbr.po
                  if po:
-@@ -491,7 +538,7 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
+@@ -489,9 +536,21 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
+         else:
+             self.reportDownloadSize(downloadpkgs, install_only)
          
++        cfr = self.tsInfo._check_future_rpmdbv
++        if (cfr is not None and
++            cfr[0] == self.tsInfo.state_counter and
++            self.tsInfo.futureRpmDBVersion() != cfr[1]):
++            msg = _("future rpmdb ver mismatched saved transaction version,")
++            if cfr[2]:
++                msg += _(" ignoring, as requested.")
++                self.logger.critical(_(msg))
++            else:
++                msg += _(" aborting.")
++                raise yum.Errors.YumBaseError(msg)
++
          # confirm with user
          if self._promptWanted():
 -            if not self.userconfirm():
@@ -381,7 +395,7 @@ index 6056d38..afa7447
                  self.verbose_logger.info(_('Exiting on user Command'))
                  return -1
  
-@@ -609,12 +656,14 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
+@@ -609,12 +668,14 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
          return resultobject.return_code
          
      def gpgsigcheck(self, pkgs):
@@ -401,7 +415,7 @@ index 6056d38..afa7447
          for po in pkgs:
              result, errmsg = self.sigCheckPkg(po)
  
-@@ -623,7 +672,8 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
+@@ -623,7 +684,8 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
                  continue            
  
              elif result == 1:
@@ -411,7 +425,7 @@ index 6056d38..afa7447
                      raise yum.Errors.YumBaseError, \
                              _('Refusing to automatically import keys when running ' \
                              'unattended.\nUse "-y" to override.')
-@@ -691,12 +741,62 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
+@@ -691,12 +753,62 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
                                       ", ".join(matches))
              self.verbose_logger.log(yum.logginglevels.INFO_2, msg)
  
@@ -480,7 +494,7 @@ index 6056d38..afa7447
          # get the list of available packages
          # iterate over the user's list
          # add packages to Transaction holding class if they match.
-@@ -710,11 +810,26 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
+@@ -710,11 +822,26 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
          for arg in userlist:
              if (arg.endswith('.rpm') and (yum.misc.re_remote_url(arg) or
                                            os.path.exists(arg))):
@@ -509,7 +523,7 @@ index 6056d38..afa7447
              except yum.Errors.InstallError:
                  self.verbose_logger.log(yum.logginglevels.INFO_2,
                                          _('No package %s%s%s available.'),
-@@ -723,6 +838,7 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
+@@ -723,6 +850,7 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
                  self._maybeYouMeant(arg)
              else:
                  done = True
@@ -517,7 +531,7 @@ index 6056d38..afa7447
          if len(self.tsInfo) > oldcount:
              change = len(self.tsInfo) - oldcount
              return 2, [P_('%d package to install', '%d packages to install', change) % change]
-@@ -732,9 +848,27 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
+@@ -732,9 +860,27 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
          return 0, [_('Nothing to do')]
          
      def updatePkgs(self, userlist, quiet=0, update_to=False):
@@ -548,7 +562,7 @@ index 6056d38..afa7447
          # if there is no userlist, then do global update below
          # this is probably 90% of the calls
          # if there is a userlist then it's for updating pkgs, not obsoleting
-@@ -745,21 +879,18 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
+@@ -745,21 +891,18 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
  
          else:
              # go through the userlist - look for items that are local rpms. If we find them
@@ -579,7 +593,7 @@ index 6056d38..afa7447
  
          if len(self.tsInfo) > oldcount:
              change = len(self.tsInfo) - oldcount
-@@ -770,9 +901,24 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
+@@ -770,9 +913,24 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
      #  Note that we aren't in __init__ yet for a couple of reasons, but we 
      # probably will get there for 3.2.28.
      def distroSyncPkgs(self, userlist):
@@ -607,7 +621,7 @@ index 6056d38..afa7447
  
          level = 'diff'
          if userlist and userlist[0] in ('full', 'diff', 'different'):
-@@ -831,6 +977,7 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
+@@ -831,6 +989,7 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
                          continue
  
                      nayi = napkg.yumdb_info
@@ -615,7 +629,7 @@ index 6056d38..afa7447
                      for apkg in self.pkgSack.searchPkgTuple(napkg.pkgtup):
                          if ('checksum_type' in nayi and
                              'checksum_data' in nayi and
-@@ -866,10 +1013,19 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
+@@ -866,10 +1025,19 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
              return 0, [_('No Packages marked for Distribution Synchronization')]
  
      def erasePkgs(self, userlist):
@@ -639,7 +653,7 @@ index 6056d38..afa7447
  
          all_rms = []
          for arg in userlist:
-@@ -884,12 +1040,24 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
+@@ -884,12 +1052,24 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
              return 0, [_('No Packages marked for removal')]
      
      def downgradePkgs(self, userlist):
@@ -667,7 +681,7 @@ index 6056d38..afa7447
          for arg in userlist:
              if (arg.endswith('.rpm') and (yum.misc.re_remote_url(arg) or
                                            os.path.exists(arg))):
-@@ -905,26 +1073,44 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
+@@ -905,26 +1085,44 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
                                          self.term.MODE['bold'], arg,
                                          self.term.MODE['normal'])
                  self._maybeYouMeant(arg)
@@ -716,7 +730,7 @@ index 6056d38..afa7447
              except yum.Errors.ReinstallRemoveError:
                  self._checkMaybeYouMeant(arg, always_output=False)
              except yum.Errors.ReinstallInstallError, e:
-@@ -940,15 +1126,31 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
+@@ -940,15 +1138,31 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
              except yum.Errors.ReinstallError, e:
                  assert False, "Shouldn't happen, but just in case"
                  self.verbose_logger.log(yum.logginglevels.INFO_2, e)
@@ -751,7 +765,7 @@ index 6056d38..afa7447
          # read in each package into a YumLocalPackage Object
          # append it to self.localPackages
          # check if it can be installed or updated based on nevra versus rpmdb
-@@ -972,20 +1174,25 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
+@@ -972,20 +1186,25 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
          return 0, [_('Nothing to do')]
  
      def returnPkgLists(self, extcmds, installed_available=False):
@@ -791,7 +805,7 @@ index 6056d38..afa7447
          special = ['available', 'installed', 'all', 'extras', 'updates', 'recent',
                     'obsoletes']
          
-@@ -1017,8 +1224,25 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
+@@ -1017,8 +1236,25 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
          return ypl
  
      def search(self, args):
@@ -819,7 +833,7 @@ index 6056d38..afa7447
          
          # call the yum module search function with lists of tags to search
          # and what to search for
-@@ -1108,9 +1332,20 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
+@@ -1108,9 +1344,20 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
          return 0, matching
  
      def deplist(self, args):
@@ -842,7 +856,7 @@ index 6056d38..afa7447
          pkgs = []
          for arg in args:
              if (arg.endswith('.rpm') and (yum.misc.re_remote_url(arg) or
-@@ -1131,10 +1366,19 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
+@@ -1131,10 +1378,19 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
          return 0, []
  
      def provides(self, args):
@@ -866,7 +880,16 @@ index 6056d38..afa7447
          old_sdup = self.conf.showdupesfromrepos
          # For output, as searchPackageProvides() is always in showdups mode
          self.conf.showdupesfromrepos = True
-@@ -1163,20 +1407,77 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
+@@ -1147,6 +1403,8 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
+             paths = set(sys.path + os.environ['PATH'].split(':'))
+             nargs = []
+             for arg in args:
++                if not arg:
++                    continue
+                 if yum.misc.re_filename(arg) or yum.misc.re_glob(arg):
+                     continue
+                 for path in paths:
+@@ -1163,20 +1421,77 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
          return 0, []
      
      def resolveDepCli(self, args):
@@ -949,17 +972,17 @@ index 6056d38..afa7447
          hdrcode = pkgcode = xmlcode = dbcode = expccode = 0
          pkgresults = hdrresults = xmlresults = dbresults = expcresults = []
          msg = self.fmtKeyValFill(_('Cleaning repos: '), 
-@@ -1228,7 +1529,19 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
+@@ -1228,7 +1543,19 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
          return code, []
  
      def returnGroupLists(self, userlist):
 +        """Print out a list of groups that match the given names or
 +        wildcards.
-+
+ 
 +        :param extcmds: a list of names or wildcards specifying
 +           groups to list
 +        :return: (exit_code, [ errors ])
- 
++
 +        exit_code is::
 +
 +            0 = we're done, exit
@@ -969,7 +992,7 @@ index 6056d38..afa7447
          uservisible=1
              
          if len(userlist) > 0:
-@@ -1254,7 +1567,7 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
+@@ -1254,7 +1581,7 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
                  msg += ' (%s)' % group.groupid
              if group.langonly:
                  msg += ' [%s]' % group.langonly
@@ -978,7 +1001,7 @@ index 6056d38..afa7447
  
          done = False
          for group in installed:
-@@ -1283,7 +1596,20 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
+@@ -1283,7 +1610,20 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
          return 0, [_('Done')]
  
      def returnGroupSummary(self, userlist):
@@ -989,9 +1012,9 @@ index 6056d38..afa7447
 +           groups to summarise. If *userlist* is an empty list, all
 +           installed and available packages will be summarised
 +        :return: (exit_code, [ errors ])
-+
-+        exit_code is::
  
++        exit_code is::
++
 +            0 = we're done, exit
 +            1 = we've errored, exit with error string
 +            2 = we've got work yet to do, onto the next stage
@@ -999,7 +1022,7 @@ index 6056d38..afa7447
          uservisible=1
              
          if len(userlist) > 0:
-@@ -1327,7 +1653,19 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
+@@ -1327,7 +1667,19 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
          return 0, [_('Done')]
      
      def returnGroupInfo(self, userlist):
@@ -1020,7 +1043,7 @@ index 6056d38..afa7447
          for strng in userlist:
              group_matched = False
              for group in self.comps.return_groups(strng):
-@@ -1339,9 +1677,19 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
+@@ -1339,9 +1691,19 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
          
          return 0, []
          
@@ -1043,7 +1066,7 @@ index 6056d38..afa7447
          pkgs_used = []
          
          for group_string in grouplist:
-@@ -1351,7 +1699,7 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
+@@ -1351,7 +1713,7 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
  
              
                  try:
@@ -1052,7 +1075,7 @@ index 6056d38..afa7447
                  except yum.Errors.GroupsError:
                      self.logger.critical(_('Warning: Group %s does not exist.'), group_string)
                      continue
-@@ -1368,8 +1716,18 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
+@@ -1368,8 +1730,18 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
              return 2, [P_('%d package to Install', '%d packages to Install', len(pkgs_used)) % len(pkgs_used)]
  
      def removeGroups(self, grouplist):
@@ -1062,9 +1085,9 @@ index 6056d38..afa7447
 +        :param grouplist: a list of names or wildcards specifying
 +           groups to be removed
 +        :return: (exit_code, [ errors ])
-+
-+        exit_code is::
  
++        exit_code is::
++
 +            0 = we're done, exit
 +            1 = we've errored, exit with error string
 +            2 = we've got work yet to do, onto the next stage
@@ -1072,7 +1095,7 @@ index 6056d38..afa7447
          pkgs_used = []
          for group_string in grouplist:
              try:
-@@ -1389,7 +1747,7 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
+@@ -1389,7 +1761,7 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
  
      def _promptWanted(self):
          # shortcut for the always-off/always-on options
@@ -1081,7 +1104,7 @@ index 6056d38..afa7447
              return False
          if self.conf.alwaysprompt:
              return True
-@@ -1400,7 +1758,6 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
+@@ -1400,7 +1772,6 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
          #  package wasn't explictly given on the command line
          for txmbr in self.tsInfo.getMembers():
              if txmbr.isDep or \
@@ -1089,7 +1112,7 @@ index 6056d38..afa7447
                     txmbr.name not in self.extcmds:
                  return True
          
-@@ -1408,11 +1765,11 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
+@@ -1408,11 +1779,11 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
          return False
  
      def usage(self):
@@ -1103,7 +1126,7 @@ index 6056d38..afa7447
          sys.stdout.write(self.optparser.get_usage())
      
      def _installable(self, pkg, ematch=False):
-@@ -1468,9 +1825,9 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
+@@ -1468,9 +1839,9 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
          return False
  
  class YumOptionParser(OptionParser):
@@ -1115,7 +1138,7 @@ index 6056d38..afa7447
  
      def __init__(self,base, **kwargs):
          # check if this is called with a utils=True/False parameter
-@@ -1488,13 +1845,23 @@ class YumOptionParser(OptionParser):
+@@ -1488,13 +1859,23 @@ class YumOptionParser(OptionParser):
          self._addYumBasicOptions()
  
      def error(self, msg):
@@ -1141,7 +1164,7 @@ index 6056d38..afa7447
          try:
              args = _filtercmdline(
                          ('--noplugins','--version','-q', '-v', "--quiet", "--verbose"), 
-@@ -1521,7 +1888,15 @@ class YumOptionParser(OptionParser):
+@@ -1521,7 +1902,15 @@ class YumOptionParser(OptionParser):
          return ret
          
      def setupYumConfig(self, args=None):
@@ -1158,7 +1181,7 @@ index 6056d38..afa7447
          if not args:
              (opts, cmds) = self.parse_args()
          else:
-@@ -1536,13 +1911,14 @@ class YumOptionParser(OptionParser):
+@@ -1536,13 +1925,14 @@ class YumOptionParser(OptionParser):
                  
              # Handle remaining options
              if opts.assumeyes:
@@ -1178,7 +1201,7 @@ index 6056d38..afa7447
                  self.base.conf.cache = 1
  
              if opts.obsoletes:
-@@ -1610,10 +1986,6 @@ class YumOptionParser(OptionParser):
+@@ -1610,10 +2000,6 @@ class YumOptionParser(OptionParser):
                      self.base.usage()
                      sys.exit(1)
  
@@ -1189,7 +1212,7 @@ index 6056d38..afa7447
              # Disable all gpg key checking, if requested.
              if opts.nogpgcheck:
                  #  Altering the normal configs. doesn't work too well, esp. with
-@@ -1640,6 +2012,14 @@ class YumOptionParser(OptionParser):
+@@ -1640,6 +2026,14 @@ class YumOptionParser(OptionParser):
          sys.exit(1)
  
      def getRoot(self,opts):
@@ -1204,7 +1227,7 @@ index 6056d38..afa7447
          self._checkAbsInstallRoot(opts)
          # If the conf file is inside the  installroot - use that.
          # otherwise look for it in the normal root
-@@ -1713,6 +2093,10 @@ class YumOptionParser(OptionParser):
+@@ -1713,6 +2107,10 @@ class YumOptionParser(OptionParser):
                          help=_("verbose operation"))
          group.add_option("-y", "--assumeyes", dest="assumeyes",
                  action="store_true", help=_("answer yes for all questions"))
@@ -1217,10 +1240,10 @@ index 6056d38..afa7447
          group.add_option("--installroot", help=_("set install root"), 
 diff --git a/completion-helper.py b/completion-helper.py
 new file mode 100755
-index 0000000..e4164f7
+index 0000000..0e4b96b
 --- /dev/null
 +++ b/completion-helper.py
-@@ -0,0 +1,83 @@
+@@ -0,0 +1,90 @@
 +#!/usr/bin/python -t
 +# -*- coding: utf-8 -*-
 +#
@@ -1246,6 +1269,7 @@ index 0000000..e4164f7
 +
 +import cli
 +import yumcommands
++from yum.Errors import GroupsError
 +
 +
 +class GroupsCompletionCommand(yumcommands.GroupsCommand):
@@ -1286,7 +1310,8 @@ index 0000000..e4164f7
 +
 +def get_pattern(extcmds):
 +    if len(extcmds) > 1 and extcmds[-1]:
-+        return shlex.split(extcmds[-1])[0] + "*"
++        try: return shlex.split(extcmds[-1])[0] + "*"
++        except ValueError: pass
 +    return "*"
 +
 +def main(args):
@@ -1297,7 +1322,12 @@ index 0000000..e4164f7
 +    base.registerCommand(RepoListCompletionCommand())
 +    base.getOptionsConfig(args)
 +    base.parseCommands()
-+    base.doCommands()
++    for repo in base.repos.listEnabled():
++        repo.skip_if_unavailable = True
++    try:
++        base.doCommands()
++    except GroupsError, e:
++        base.logger.error(e)
 +
 +if __name__ == "__main__":
 +    try:
@@ -2125,7 +2155,7 @@ index 1a8202a..604377b 100644
  .br
  Configuration Option: \fBrpmverbosity\fP
 diff --git a/docs/yum.conf.5 b/docs/yum.conf.5
-index 515aa73..df172fa 100644
+index 515aa73..b456074 100644
 --- a/docs/yum.conf.5
 +++ b/docs/yum.conf.5
 @@ -114,15 +114,27 @@ are causing problems from the transaction.
@@ -2199,7 +2229,7 @@ index 515aa73..df172fa 100644
  \fBinstallroot \fR
  Specifies an alternative installroot, relative to which all packages will be
  installed. 
-@@ -300,6 +337,14 @@ with the \fBthrottle\fR option (above). If \fBthrottle\fR is a percentage and
+@@ -300,6 +337,21 @@ with the \fBthrottle\fR option (above). If \fBthrottle\fR is a percentage and
  ignored. Default is `0' (no bandwidth throttling). 
  
  .IP
@@ -2211,10 +2241,17 @@ index 515aa73..df172fa 100644
 +`6' or `IPv6': resolve to IPv6 addresses only.
 +
 +.IP
++\fBmax_connections \fR
++
++The maximum number of simultaneous connections.  This overrides the urlgrabber
++default of 5 connections.  Note that there are also implicit per-mirror limits
++and the downloader honors these too.
++
++.IP
  \fBsslcacert \fR
  Path to the directory containing the databases of the certificate authorities
  yum should use to verify SSL certificates. Defaults to none - uses system
-@@ -331,6 +376,15 @@ Path to the SSL client key yum should use to connect to repos/remote sites
+@@ -331,6 +383,15 @@ Path to the SSL client key yum should use to connect to repos/remote sites
  Defaults to none.
  
  .IP
@@ -2230,10 +2267,12 @@ index 515aa73..df172fa 100644
  \fBhistory_record \fR
  Boolean - should yum record history entries for transactions. This takes some
  disk space, and some extra time in the transactions. But it allows how to know a
-@@ -595,6 +649,23 @@ package's dependencies. If any of them are no longer required by any other
+@@ -593,8 +654,50 @@ See color_list_installed_older for possible values.
+ When removing packages (by removal, update or obsoletion) go through each
+ package's dependencies. If any of them are no longer required by any other 
  package then also mark them to be removed.
- Boolean (1, 0, True, False, yes,no) Defaults to False
- 
++Boolean (1, 0, True, False, yes, no) Defaults to False
++
 +.IP
 +\fBupgrade_requirements_on_install \fR
 +When installing/reinstalling/upgrading packages go through each package's
@@ -2245,16 +2284,41 @@ index 515aa73..df172fa 100644
 +When upgrading a package do we recheck any requirements that existed in the old
 +package. Turning this on shouldn't do anything but slow yum depsolving down,
 +however using rpm --nodeps etc. can break the rpmdb and then this will help.
-+Boolean (1, 0, True, False, yes,no) Defaults to False
-+
+ Boolean (1, 0, True, False, yes,no) Defaults to False
+ 
 +.IP
 +\fBreset_nice \fR
 +If set to true then yum will try to reset the nice value to zero, before
 +running an rpm transaction. Defaults to True.
++
++\fBexit_on_lock\fR
++Should the yum client exit immediately when something else has the lock.
++Boolean (1, 0, True, False, yes, no) Defaults to False
++
++.IP
++\fBloadts_ignoremissing\fR
++Should the load-ts command ignore packages that are missing. This includes
++packages in the TS to be removed, which aren't installed, and packages in the
++TS to be added, which aren't available.
++Boolean (1, 0, True, False, yes, no) Defaults to False
++
++.IP
++\fBloadts_ignorerpm\fR
++Should the load-ts command ignore the rpmdb version (yum version nogroups) or
++abort if there is a mismatch between the TS file and the current machine.
++Boolean (1, 0, True, False, yes, no) Defaults to False
++
++.IP
++\fBloadts_ignorenewrpm\fR
++Should the load-ts command ignore the future rpmdb version or
++abort if there is a mismatch between the TS file and what will happen on the
++current machine.
++Note that if loadts_ignorerpm is True, this option does nothing.
++Boolean (1, 0, True, False, yes, no) Defaults to False
  
  
  .SH "[repository] OPTIONS"
-@@ -755,6 +826,11 @@ repository.
+@@ -755,6 +858,11 @@ repository.
  Overrides the \fBbandwidth\fR option from the [main] section for this
  repository.
  
@@ -2266,7 +2330,7 @@ index 515aa73..df172fa 100644
  
  .IP
  \fBsslcacert \fR
-@@ -776,6 +852,10 @@ repository.
+@@ -776,6 +884,10 @@ repository.
  Overrides the \fBsslclientkey\fR option from the [main] section for this
  repository.
  
@@ -2277,6 +2341,18 @@ index 515aa73..df172fa 100644
  
  .IP
  \fBmetadata_expire \fR
+@@ -824,7 +936,11 @@ as greater/less than any other. defaults to 1000
+ If set to True yum will continue running if this repository cannot be 
+ contacted for any reason. This should be set carefully as all repos are consulted
+ for any given command. Defaults to False.
++
+ .IP
++\fBasync \fR
++If set to True Yum will download packages and metadata from this repo in
++parallel, if possible.  Defaults to True.
+ 
+ .SH "URL INCLUDE SYNTAX"
+ .LP
 diff --git a/etc/0yum.cron b/etc/0yum.cron
 deleted file mode 100755
 index 0cfaa4b..0000000
@@ -2631,7 +2707,7 @@ index c60fa08..0000000
 -ts run
 -exit
 diff --git a/etc/yum.bash b/etc/yum.bash
-index f1e06e8..5945c6f 100644
+index f1e06e8..b21c594 100644
 --- a/etc/yum.bash
 +++ b/etc/yum.bash
 @@ -1,53 +1,17 @@
@@ -2641,7 +2717,8 @@ index f1e06e8..5945c6f 100644
 -#   1 = argument to "yum list" (all, available, updates etc)
 -#   2 = current word to be completed
 -_yum_list()
--{
++_yum_helper()
+ {
 -    # Fail fast for things that look like paths.
 -    [[ $2 == */* || $2 == [.~]* ]] && return
 -
@@ -2664,8 +2741,7 @@ index f1e06e8..5945c6f 100644
 -#   1 = argument to "yum repolist" (enabled, disabled etc)
 -#   2 = current word to be completed
 -_yum_repolist()
-+_yum_helper()
- {
+-{
 -    # TODO: add -d 0 when http://yum.baseurl.org/ticket/29 is fixed
 -    #       (for now --noplugins is used to get rid of "Loaded plugins: ...")
 -    # Drop first ("repo id      repo name") and last ("repolist: ...") rows -
@@ -2690,8 +2766,8 @@ index f1e06e8..5945c6f 100644
 -    COMPREPLY=( $( compgen -W "$( ${yum:-yum} -C grouplist $1 "$2*" \
 -        2>/dev/null | sed -ne 's/^[[:space:]]\{1,\}\(.\{1,\}\)/\1/p' )" \
 -        -- "$2" ) )
-+    # Fail fast for things that look like paths.
-+    [[ $2 == */* || $2 == [.~]* ]] && return
++    # Fail fast for things that look like paths or options.
++    [[ $2 == */* || $2 == [.~-]* ]] && return
 +    _yum_helper list "$@"
  }
  
@@ -2759,8 +2835,8 @@ index f1e06e8..5945c6f 100644
 -        groupinfo groupinstall grouplist groupremove help history info install
 -        list makecache provides reinstall remove repolist resolvedep search
 -        shell update upgrade version )
-+        groups help history info install list makecache provides reinstall
-+        remove repolist search shell update upgrade version )
++        groups help history info install list load-transaction makecache provides
++        reinstall remove repolist search shell update upgrade version )
  
      local i c cmd subcmd
      for (( i=1; i < ${#words[@]}-1; i++ )) ; do
@@ -2769,7 +2845,7 @@ index f1e06e8..5945c6f 100644
          for c in ${cmds[@]} check-rpmdb distribution-synchronization erase \
 -            groupupdate grouperase localinstall localupdate whatprovides ; do
 +            group groupinfo groupinstall grouplist groupremove groupupdate \
-+            grouperase install-na localinstall localupdate whatprovides ; do
++            grouperase install-na load-ts localinstall localupdate whatprovides ; do
              [[ ${words[i]} == $c ]] && cmd=$c && break
          done
      done
@@ -2889,7 +2965,7 @@ index f1e06e8..5945c6f 100644
                      ;;
              esac
              return 0
-@@ -288,13 +285,20 @@ _yum()
+@@ -288,42 +285,56 @@ _yum()
              ;;
  
          install)
@@ -2912,7 +2988,16 @@ index f1e06e8..5945c6f 100644
                  COMPREPLY=( $( compgen -W 'all available updates installed
                      extras obsoletes recent' -- "$cur" ) )
              return 0
-@@ -306,24 +310,26 @@ _yum()
+             ;;
+ 
++        load-transaction|load-ts)
++            COMPREPLY=( $( compgen -f -o plusdirs -X '!*.yumtx' -- "$cur" ) )
++            return 0
++            ;;
++
+         localinstall|localupdate)
+             _yum_binrpmfiles "$cur"
+             return 0
              ;;
  
          repolist)
@@ -2944,7 +3029,7 @@ index f1e06e8..5945c6f 100644
                  COMPREPLY=( $( compgen -W 'all installed available nogroups
                      grouplist groupinfo' -- "$cur" ) )
              return 0
-@@ -337,7 +343,11 @@ _yum()
+@@ -337,7 +348,11 @@ _yum()
  
      $split && return 0
  
@@ -147960,20 +148045,22 @@ index 704a726..05fe6bf 100644
 -
 -
 diff --git a/rpmUtils/arch.py b/rpmUtils/arch.py
-index 6082005..7d67907 100644
+index 6082005..2226dc5 100644
 --- a/rpmUtils/arch.py
 +++ b/rpmUtils/arch.py
-@@ -2,6 +2,9 @@
+@@ -2,6 +2,11 @@
  #
  
  import os
 +import rpm
++import ctypes
++import struct
 +
 +_ppc64_native_is_best = False
  
  # dict mapping arch -> ( multicompat, best personality, biarch personality )
  multilibArches = { "x86_64":  ( "athlon", "x86_64", "athlon" ),
-@@ -10,6 +13,8 @@ multilibArches = { "x86_64":  ( "athlon", "x86_64", "athlon" ),
+@@ -10,6 +15,8 @@ multilibArches = { "x86_64":  ( "athlon", "x86_64", "athlon" ),
                     "ppc64":   ( "ppc", "ppc", "ppc64" ),
                     "s390x":   ( "s390", "s390x", "s390" ),
                     }
@@ -147982,7 +148069,15 @@ index 6082005..7d67907 100644
  
  arches = {
      # ia32
-@@ -61,6 +66,13 @@ arches = {
+@@ -26,6 +33,7 @@ arches = {
+     "ia32e": "x86_64",
+     
+     # ppc
++    "ppc64p7": "ppc64",
+     "ppc64pseries": "ppc64",
+     "ppc64iseries": "ppc64",    
+     "ppc64": "ppc",
+@@ -61,6 +69,13 @@ arches = {
      "armv5tejl": "armv5tel",
      "armv5tel": "noarch",
  
@@ -147996,7 +148091,54 @@ index 6082005..7d67907 100644
      # super-h 
      "sh4a": "sh4",
      "sh4": "noarch",
-@@ -231,6 +243,13 @@ def getCanonX86Arch(arch):
+@@ -70,6 +85,13 @@ arches = {
+     "ia64": "noarch",
+     }
+ 
++#  Will contain information parsed from /proc/self/auxv via _parse_auxv().
++# Should move into rpm really.
++_aux_vector = {
++    "platform": "",
++    "hwcap": 0,
++    }
++
+ def legitMultiArchesInSameLib(arch=None):
+     # this is completely crackrock - if anyone has a better way I
+     # am all ears
+@@ -210,6 +232,32 @@ def _try_read_cpuinfo():
+     except:
+         return []
+ 
++def _parse_auxv():
++    """ Read /proc/self/auxv and parse it into global dict for easier access
++        later on, very similar to what rpm does. """
++    # In case we can't open and read /proc/self/auxv, just return
++    try:
++        data = open("/proc/self/auxv", "rb").read()
++    except:
++        return
++
++    # Define values from /usr/include/elf.h
++    AT_PLATFORM = 15
++    AT_HWCAP = 16
++    fmtlen = struct.calcsize("LL")
++    offset = 0
++    platform = ctypes.c_char_p()
++
++    # Parse the data and fill in _aux_vector dict
++    while offset <= len(data) - fmtlen:
++        at_type, at_val = struct.unpack_from("LL", data, offset)
++        if at_type == AT_PLATFORM:
++            platform.value = at_val
++            _aux_vector["platform"] = platform.value
++        if at_type == AT_HWCAP:
++            _aux_vector["hwcap"] = at_val
++        offset = offset + fmtlen
++
+ def getCanonX86Arch(arch):
+     # 
+     if arch == "i586":
+@@ -231,6 +279,13 @@ def getCanonX86Arch(arch):
  
      return arch
  
@@ -148010,7 +148152,30 @@ index 6082005..7d67907 100644
  def getCanonPPCArch(arch):
      # FIXME: should I do better handling for mac, etc?
      if arch != "ppc64":
-@@ -308,6 +327,8 @@ def getCanonArch(skipRpmPlatform = 0):
+@@ -241,6 +296,17 @@ def getCanonPPCArch(arch):
+         if line.find("machine") != -1:
+             machine = line.split(':')[1]
+             break
++
++    platform = _aux_vector["platform"]
++    if machine is None and not platform:
++        return arch
++
++    try:
++        if platform.startswith("power") and int(platform[5:]) >= 7:
++            return "ppc64p7"
++    except:
++        pass
++
+     if machine is None:
+         return arch
+ 
+@@ -305,9 +371,13 @@ def getCanonArch(skipRpmPlatform = 0):
+         
+     arch = os.uname()[4]
+ 
++    _parse_auxv()
++
      if (len(arch) == 4 and arch[0] == "i" and arch[2:4] == "86"):
          return getCanonX86Arch(arch)
  
@@ -148019,7 +148184,7 @@ index 6082005..7d67907 100644
      if arch.startswith("ppc"):
          return getCanonPPCArch(arch)
      if arch.startswith("sparc"):
-@@ -339,7 +360,7 @@ def getBestArch(myarch=None):
+@@ -339,7 +409,7 @@ def getBestArch(myarch=None):
      if arch.startswith("sparc64"):
          arch = multilibArches[arch][1]
  
@@ -148028,7 +148193,7 @@ index 6082005..7d67907 100644
          arch = 'ppc'
  
      return arch
-@@ -357,8 +378,12 @@ def getBaseArch(myarch=None):
+@@ -357,8 +427,12 @@ def getBaseArch(myarch=None):
  
      if myarch.startswith("sparc64"):
          return "sparc"
@@ -148309,6 +148474,82 @@ index 7af3f16..ea47b03 100644
  
      def testUpdate_so_req_diff_arch(self):
          rpo1 = FakePackage('foozoomer')
+diff --git a/test/revdepupdatetests.py b/test/revdepupdatetests.py
+new file mode 100644
+index 0000000..a98341d
+--- /dev/null
++++ b/test/revdepupdatetests.py
+@@ -0,0 +1,70 @@
++from testbase import *
++
++class RevdepUpdateTests(OperationsTests):
++
++    @staticmethod
++    def buildPkgs(pkgs, *args):
++        """ This test checks that remove_old_deps handles reverse 
++        dependencies properly during yum update. Specifically, 
++        remove_old_deps should remove precisely the packages which are not 
++        required by any package currently installed or pending 
++        installation. Two cases:
++        
++        For packages A, B, we write A -> B if B requires A. Packages 
++        with a dep prefix are dep-installed.
++
++        1) Installed: dep1 -> dep2 -> pkg1 <- dep3 and dep3 -> dep2
++           Update: pkg1, which requires dep2 but no longer requires dep3.
++           Correct outcome: dep1, dep2, dep3, pkg1, since dep2 still 
++           needs dep3.
++
++        2) Installed: dep1 -> dep2 -> pkg1 <- dep3 and dep3 -> dep2
++           Update: pkg1, which now requires only dep1
++           Correct outcome: dep1, pkg1, since dep2 and dep3 are 
++           no longer needed.
++           
++        """
++
++        
++        pkgs.installed_1 = FakePackage('dep1', '1', '0', '0', 'noarch')
++        pkgs.installed_1.yumdb_info.reason = 'dep'
++        
++        pkgs.installed_2 = FakePackage('dep2', '1', '0', '0', 'noarch')
++        pkgs.installed_2.yumdb_info.reason = 'dep'
++        
++        pkgs.installed_3 = FakePackage('pkg1', '1', '0', '0', 'noarch')
++        pkgs.installed_3.yumdb_info.reason = 'user'
++
++        pkgs.installed_4 = FakePackage('dep3', '1', '0', '0', 'noarch')
++        pkgs.installed_4.yumdb_info.reason = 'dep'
++        
++        pkgs.installed_1.addRequiringPkg(pkgs.installed_2)
++        pkgs.installed_2.addRequiringPkg(pkgs.installed_3)
++        pkgs.installed_4.addRequiringPkg(pkgs.installed_2)
++
++        pkgs.installed_2.addRequiresPkg(pkgs.installed_1)
++        pkgs.installed_2.addRequiresPkg(pkgs.installed_4)
++        pkgs.installed_3.addRequiresPkg(pkgs.installed_4)
++        pkgs.installed_3.addRequiresPkg(pkgs.installed_2)
++
++        pkgs.update_2 = FakePackage('dep2', '2', '0', '0', 'noarch')
++        pkgs.update_2.addRequires('dep1', 'EQ', ('0', '1', '0'))
++
++        pkgs.update_3 = FakePackage('pkg1', '2', '0', '0', 'noarch')
++        pkgs.update_3.addRequires('dep2', 'EQ', ('0', '1', '0'))
++
++        pkgs.update_4 = FakePackage('pkg1', '2', '0', '0', 'noarch')
++        pkgs.update_4.addRequires('dep1', 'EQ', ('0', '1', '0'))
++
++    def testUpdate(self):
++        p = self.pkgs
++        res, msg = self.runOperation(['update'], [p.installed_1, p.installed_2, p.installed_3, p.installed_4], [p.update_3])
++        self.assert_(res=='ok', msg)
++        self.assertResult( (p.installed_1, p.installed_2, p.update_3, p.installed_4) )
++    
++    def testUpdate2(self):
++        p = self.pkgs
++        res, msg = self.runOperation(['update'], [p.installed_1, p.installed_2, p.installed_3, p.installed_4], [p.update_4])
++        self.assert_(res=='ok', msg)
++        self.assertResult( (p.installed_1, p.update_4) )
++
 diff --git a/test/simpleobsoletestests.py b/test/simpleobsoletestests.py
 index 97a9923..70dde98 100644
 --- a/test/simpleobsoletestests.py
@@ -149127,10 +149368,10 @@ index ced6ba0..08b09fb
              return_code = self.doTransaction()
 diff --git a/yum-cron/Makefile b/yum-cron/Makefile
 new file mode 100644
-index 0000000..d68659a
+index 0000000..34cb397
 --- /dev/null
 +++ b/yum-cron/Makefile
-@@ -0,0 +1,19 @@
+@@ -0,0 +1,21 @@
 +all:
 +	echo "Nothing to do"
 +
@@ -149143,7 +149384,9 @@ index 0000000..d68659a
 +	mkdir -p $(DESTDIR)/usr/sbin
 +	mkdir -p $(DESTDIR)/etc/sysconfig
 +	mkdir -p $(DESTDIR)/usr/share/yum-cron
-+	install -D -m 755 yum-update.cron.sh $(DESTDIR)/etc/cron.daily/yum-update.cron
++# Install yum-update.cron as 0yum-update.cron so it runs before items like
++# manpage update, mlocate, and prelink
++	install -D -m 755 yum-update.cron.sh $(DESTDIR)/etc/cron.daily/0yum-update.cron
 +	install -D -m 755 yum-cleanup.cron.sh $(DESTDIR)/etc/cron.daily/yum-cleanup.cron
 +	install -D -m 755 yum-cron.sysvinit $(DESTDIR)/etc/rc.d/init.d/yum-cron
 +	install -D -m 755 yum-cron.sh $(DESTDIR)/usr/sbin/yum-cron
@@ -149408,7 +149651,7 @@ index 0000000..e300fa7
 +exit 0
 diff --git a/yum-cron/yum-cron.sysconfig b/yum-cron/yum-cron.sysconfig
 new file mode 100644
-index 0000000..4c8c40d
+index 0000000..53477d3
 --- /dev/null
 +++ b/yum-cron/yum-cron.sysconfig
 @@ -0,0 +1,92 @@
@@ -149465,7 +149708,7 @@ index 0000000..4c8c40d
 +#SYSTEMNAME="" 
 +
 +# Scheduling Options (used by the default cron scripts,
-+# /etc/cron.daily/yum-cleanup.cron and /etc/cron.daily/yum-update.cron)
++# /etc/cron.daily/yum-cleanup.cron and /etc/cron.daily/0yum-update.cron)
 +# 
 +#   Note that if you use a different cron configuration (for example,
 +#   removing the default scripts and adding an entry in /etc/cron.d),
@@ -150214,7 +150457,7 @@ index 1ce4720..25e3022
      gobject.threads_init()
      dbus.glib.threads_init()
 diff --git a/yum.spec b/yum.spec
-index abd203f..572112a 100644
+index abd203f..65c62a9 100644
 --- a/yum.spec
 +++ b/yum.spec
 @@ -1,24 +1,51 @@
@@ -150451,7 +150694,7 @@ index abd203f..572112a 100644
 -%{_sysconfdir}/cron.daily/0yum.cron
 -%config(noreplace) %{_sysconfdir}/yum/yum-daily.yum
 -%config(noreplace) %{_sysconfdir}/yum/yum-weekly.yum
-+%config(noreplace) %{_sysconfdir}/cron.daily/yum-update.cron
++%config(noreplace) %{_sysconfdir}/cron.daily/0yum-update.cron
 +%config(noreplace) %{_sysconfdir}/cron.daily/yum-cleanup.cron
  %{_sysconfdir}/rc.d/init.d/yum-cron
 +%{_sbindir}/yum-cron
@@ -150481,7 +150724,7 @@ index abd203f..572112a 100644
  - 3.4.1
  - umask bug fix.
 diff --git a/yum/__init__.py b/yum/__init__.py
-index 99039e0..3680356 100644
+index 99039e0..4650639 100644
 --- a/yum/__init__.py
 +++ b/yum/__init__.py
 @@ -46,8 +46,13 @@ import operator
@@ -150657,7 +150900,20 @@ index 99039e0..3680356 100644
  
          if debuglevel != None:
              startupconf.debuglevel = debuglevel
-@@ -367,22 +404,36 @@ class YumBase(depsolve.Depsolve):
+@@ -336,6 +373,12 @@ class YumBase(depsolve.Depsolve):
+ 
+         self._conf = config.readMainConfig(startupconf)
+ 
++        # update urlgrabber defaults
++        mc = self._conf.max_connections
++        if mc > 0:
++            default_grabber.opts.max_connections = mc
++        default_grabber.opts.timedhosts = self._conf.cachedir + '/timedhosts'
++
+         #  We don't want people accessing/altering preconf after it becomes
+         # worthless. So we delete it, and thus. it'll raise AttributeError
+         del self.preconf
+@@ -367,22 +410,36 @@ class YumBase(depsolve.Depsolve):
      def doLoggingSetup(self, debuglevel, errorlevel,
                         syslog_ident=None, syslog_facility=None,
                         syslog_device='/dev/log'):
@@ -150701,7 +150957,17 @@ index 99039e0..3680356 100644
          if repo_age is None:
              repo_age = os.stat(repofn)[8]
          
-@@ -429,7 +480,15 @@ class YumBase(depsolve.Depsolve):
+@@ -391,8 +448,7 @@ class YumBase(depsolve.Depsolve):
+         try:
+             parser.readfp(confpp_obj)
+         except ParsingError, e:
+-            msg = str(e)
+-            raise Errors.ConfigError, msg
++            raise Errors.ConfigError(exception2msg(e))
+ 
+         # Check sections in the .repo file that was just slurped up
+         for section in parser.sections():
+@@ -429,7 +485,15 @@ class YumBase(depsolve.Depsolve):
  
                  thisrepo.base_persistdir = self.conf._repos_persistdir
  
@@ -150718,7 +150984,7 @@ index 99039e0..3680356 100644
              if thisrepo.id in self.repo_setopts:
                  for opt in self.repo_setopts[thisrepo.id].items:
                      if not hasattr(thisrepo, opt):
-@@ -440,6 +499,20 @@ class YumBase(depsolve.Depsolve):
+@@ -440,6 +504,20 @@ class YumBase(depsolve.Depsolve):
              if validate and not validate(thisrepo):
                  continue
                      
@@ -150739,7 +151005,7 @@ index 99039e0..3680356 100644
              # Got our list of repo objects, add them to the repos
              # collection
              try:
-@@ -448,8 +521,11 @@ class YumBase(depsolve.Depsolve):
+@@ -448,8 +526,11 @@ class YumBase(depsolve.Depsolve):
                  self.logger.warning(e)
          
      def getReposFromConfig(self):
@@ -150753,7 +151019,16 @@ index 99039e0..3680356 100644
          # Read .repo files from directories specified by the reposdir option
          # (typically /etc/yum/repos.d)
          repo_config_age = self.conf.config_file_age
-@@ -472,12 +548,13 @@ class YumBase(depsolve.Depsolve):
+@@ -466,18 +547,22 @@ class YumBase(depsolve.Depsolve):
+ 
+             if os.path.isdir(reposdir):
+                 for repofn in sorted(glob.glob('%s/*.repo' % reposdir)):
++                    if not os.access(repofn, os.R_OK):
++                        self.logger.warning(_("Skipping unreadable repository %s"), repr(repofn))
++                        continue
+                     thisrepo_age = os.stat(repofn)[8]
+                     if thisrepo_age < repo_config_age:
+                         thisrepo_age = repo_config_age
                      self.getReposFromConfigFile(repofn, repo_age=thisrepo_age)
  
      def readRepoConfig(self, parser, section):
@@ -150772,7 +151047,17 @@ index 99039e0..3680356 100644
          repo = yumRepo.YumRepository(section)
          try:
              repo.populate(parser, section, self.conf)
-@@ -500,31 +577,31 @@ class YumBase(depsolve.Depsolve):
+@@ -493,38 +578,40 @@ class YumBase(depsolve.Depsolve):
+         repo.name = to_unicode(repo.name)
+ 
+         # Set attributes not from the config file
++        repo.old_base_cache_dir = getattr(self, '_old_cachedir', '')
+         repo.basecachedir = self.conf.cachedir
+         repo.yumvar.update(self.conf.yumvar)
+         repo.cfg = parser
+-
++        # Enable parallel downloading
++        repo._async = repo.async
          return repo
  
      def disablePlugins(self):
@@ -150825,7 +151110,7 @@ index 99039e0..3680356 100644
          if isinstance(self.plugins, plugins.YumPlugins):
              raise RuntimeError(_("plugins already initialised"))
  
-@@ -533,6 +610,8 @@ class YumBase(depsolve.Depsolve):
+@@ -533,6 +620,8 @@ class YumBase(depsolve.Depsolve):
  
      
      def doRpmDBSetup(self):
@@ -150834,7 +151119,7 @@ index 99039e0..3680356 100644
          warnings.warn(_('doRpmDBSetup() will go away in a future version of Yum.\n'),
                  Errors.YumFutureDeprecationWarning, stacklevel=2)
  
-@@ -552,7 +631,8 @@ class YumBase(depsolve.Depsolve):
+@@ -552,7 +641,8 @@ class YumBase(depsolve.Depsolve):
          return self._rpmdb
  
      def closeRpmDB(self):
@@ -150844,7 +151129,7 @@ index 99039e0..3680356 100644
          if self._rpmdb is not None:
              self._rpmdb.ts = None
              self._rpmdb.dropCachedData()
-@@ -567,6 +647,12 @@ class YumBase(depsolve.Depsolve):
+@@ -567,6 +657,12 @@ class YumBase(depsolve.Depsolve):
          self._ts = None
  
      def doRepoSetup(self, thisrepo=None):
@@ -150857,7 +151142,7 @@ index 99039e0..3680356 100644
          warnings.warn(_('doRepoSetup() will go away in a future version of Yum.\n'),
                  Errors.YumFutureDeprecationWarning, stacklevel=2)
  
-@@ -630,6 +716,14 @@ class YumBase(depsolve.Depsolve):
+@@ -630,6 +726,14 @@ class YumBase(depsolve.Depsolve):
          self._repos = RepoStorage(self)
      
      def doSackSetup(self, archlist=None, thisrepo=None):
@@ -150872,7 +151157,7 @@ index 99039e0..3680356 100644
          warnings.warn(_('doSackSetup() will go away in a future version of Yum.\n'),
                  Errors.YumFutureDeprecationWarning, stacklevel=2)
  
-@@ -711,6 +805,9 @@ class YumBase(depsolve.Depsolve):
+@@ -711,6 +815,9 @@ class YumBase(depsolve.Depsolve):
              
             
      def doUpdateSetup(self):
@@ -150882,7 +151167,7 @@ index 99039e0..3680356 100644
          warnings.warn(_('doUpdateSetup() will go away in a future version of Yum.\n'),
                  Errors.YumFutureDeprecationWarning, stacklevel=2)
  
-@@ -765,6 +862,8 @@ class YumBase(depsolve.Depsolve):
+@@ -765,6 +872,8 @@ class YumBase(depsolve.Depsolve):
          return self._up
      
      def doGroupSetup(self):
@@ -150891,7 +151176,16 @@ index 99039e0..3680356 100644
          warnings.warn(_('doGroupSetup() will go away in a future version of Yum.\n'),
                  Errors.YumFutureDeprecationWarning, stacklevel=2)
  
-@@ -837,7 +936,10 @@ class YumBase(depsolve.Depsolve):
+@@ -829,7 +938,7 @@ class YumBase(depsolve.Depsolve):
+             try:
+                 self._comps.add(groupfile)
+             except (Errors.GroupsError,Errors.CompsException), e:
+-                msg = _('Failed to add groups file for repository: %s - %s') % (repo, str(e))
++                msg = _('Failed to add groups file for repository: %s - %s') % (repo, exception2msg(e))
+                 self.logger.critical(msg)
+             else:
+                 repo.groups_added = True
+@@ -837,7 +946,10 @@ class YumBase(depsolve.Depsolve):
          if self._comps.compscount == 0:
              raise Errors.GroupsError, _('No Groups Available in any repository')
  
@@ -150903,7 +151197,16 @@ index 99039e0..3680356 100644
          self.verbose_logger.debug('group time: %0.3f' % (time.time() - group_st))                
          return self._comps
  
-@@ -881,9 +983,18 @@ class YumBase(depsolve.Depsolve):
+@@ -868,7 +980,7 @@ class YumBase(depsolve.Depsolve):
+                     # feed it into _tags.add()
+                     self._tags.add(repo.id, tag_sqlite)
+                 except (Errors.RepoError, Errors.PkgTagsError), e:
+-                    msg = _('Failed to add Pkg Tags for repository: %s - %s') % (repo, str(e))
++                    msg = _('Failed to add Pkg Tags for repository: %s - %s') % (repo, exception2msg(e))
+                     self.logger.critical(msg)
+                     
+                 
+@@ -881,9 +993,18 @@ class YumBase(depsolve.Depsolve):
          if self._history is None:
              pdb_path = self.conf.persistdir + "/history"
              self._history = yum.history.YumHistory(root=self.conf.installroot,
@@ -150923,7 +151226,7 @@ index 99039e0..3680356 100644
      # properties so they auto-create themselves with defaults
      repos = property(fget=lambda self: self._getRepos(),
                       fset=lambda self, value: setattr(self, "_repos", value),
-@@ -921,6 +1032,11 @@ class YumBase(depsolve.Depsolve):
+@@ -921,6 +1042,11 @@ class YumBase(depsolve.Depsolve):
                         fdel=lambda self: setattr(self, "_history", None),
                         doc="Yum History Object")
  
@@ -150935,7 +151238,7 @@ index 99039e0..3680356 100644
      pkgtags = property(fget=lambda self: self._getTags(),
                         fset=lambda self, value: setattr(self, "_tags",value),
                         fdel=lambda self: setattr(self, "_tags", None),
-@@ -928,9 +1044,10 @@ class YumBase(depsolve.Depsolve):
+@@ -928,9 +1054,10 @@ class YumBase(depsolve.Depsolve):
      
      
      def doSackFilelistPopulate(self):
@@ -150949,7 +151252,7 @@ index 99039e0..3680356 100644
          necessary = False
          
          # I can't think of a nice way of doing this, we have to have the sack here
-@@ -951,8 +1068,12 @@ class YumBase(depsolve.Depsolve):
+@@ -951,8 +1078,12 @@ class YumBase(depsolve.Depsolve):
              self.repos.populateSack(mdtype='filelists')
             
      def yumUtilsMsg(self, func, prog):
@@ -150964,7 +151267,7 @@ index 99039e0..3680356 100644
          if self.rpmdb.contains(name="yum-utils"):
              return
  
-@@ -964,8 +1085,17 @@ class YumBase(depsolve.Depsolve):
+@@ -964,8 +1095,17 @@ class YumBase(depsolve.Depsolve):
               (hibeg, prog, hiend))
  
      def buildTransaction(self, unfinished_transactions_check=True):
@@ -150984,7 +151287,7 @@ index 99039e0..3680356 100644
          if (unfinished_transactions_check and
              misc.find_unfinished_transactions(yumlibpath=self.conf.persistdir)):
              msg = _('There are unfinished transactions remaining. You might ' \
-@@ -1004,7 +1134,7 @@ class YumBase(depsolve.Depsolve):
+@@ -1004,7 +1144,7 @@ class YumBase(depsolve.Depsolve):
              # If transaction was changed by postresolve plugins then we should run skipbroken again
              (rescode, restring) = self._doSkipBroken(rescode, restring, clear_skipped=False )
  
@@ -150993,7 +151296,7 @@ index 99039e0..3680356 100644
              self.tsInfo.pkgSack.dropCachedData()
  
          # FIXME: This is horrible, see below and yummain. Maybe create a real
-@@ -1242,13 +1372,15 @@ class YumBase(depsolve.Depsolve):
+@@ -1242,13 +1382,15 @@ class YumBase(depsolve.Depsolve):
          if None in pkgtup:
              return None
          return pkgtup
@@ -151013,7 +151316,7 @@ index 99039e0..3680356 100644
          if pkgtup is None:
              return
          self._not_found_i[pkgtup] = YumNotFoundPackage(pkgtup)
-@@ -1454,8 +1586,14 @@ class YumBase(depsolve.Depsolve):
+@@ -1454,8 +1596,14 @@ class YumBase(depsolve.Depsolve):
          return probs
  
      def runTransaction(self, cb):
@@ -151029,7 +151332,7 @@ index 99039e0..3680356 100644
          self.plugins.run('pretrans')
  
          #  We may want to put this other places, eventually, but for now it's
-@@ -1516,10 +1654,23 @@ class YumBase(depsolve.Depsolve):
+@@ -1516,10 +1664,23 @@ class YumBase(depsolve.Depsolve):
                  pass
          self._ts_save_file = None
          
@@ -151053,7 +151356,7 @@ index 99039e0..3680356 100644
          
          # make resultobject - just a plain yumgenericholder object
          resultobject = misc.GenericHolder()
-@@ -1567,13 +1718,24 @@ class YumBase(depsolve.Depsolve):
+@@ -1567,13 +1728,24 @@ class YumBase(depsolve.Depsolve):
          self.plugins.run('posttrans')
          # sync up what just happened versus what is in the rpmdb
          if not self.ts.isTsFlagSet(rpm.RPMTRANS_FLAG_TEST):
@@ -151083,7 +151386,7 @@ index 99039e0..3680356 100644
          # check to see that the rpmdb and the tsInfo roughly matches
          # push package object metadata outside of rpmdb into yumdb
          # delete old yumdb metadata entries
-@@ -1584,9 +1746,16 @@ class YumBase(depsolve.Depsolve):
+@@ -1584,9 +1756,16 @@ class YumBase(depsolve.Depsolve):
          #    that there is not also an install of this pkg in the tsInfo (reinstall)
          # for any kind of install add from_repo to the yumdb, and the cmdline
          # and the install reason
@@ -151100,7 +151403,7 @@ index 99039e0..3680356 100644
          for txmbr in self.tsInfo:
              if txmbr.output_state in TS_INSTALL_STATES:
                  if not self.rpmdb.contains(po=txmbr.po):
-@@ -1596,7 +1765,9 @@ class YumBase(depsolve.Depsolve):
+@@ -1596,7 +1775,9 @@ class YumBase(depsolve.Depsolve):
                                             ' but is not!' % txmbr.po))
                      # Note: Get Panu to do te.Failed() so we don't have to
                      txmbr.output_state = TS_FAILED
@@ -151110,7 +151413,7 @@ index 99039e0..3680356 100644
                  po = self.getInstalledPackageObject(txmbr.pkgtup)
                  rpo = txmbr.po
                  po.yumdb_info.from_repo = rpo.repoid
-@@ -1630,6 +1801,10 @@ class YumBase(depsolve.Depsolve):
+@@ -1630,6 +1811,10 @@ class YumBase(depsolve.Depsolve):
                      if md:
                          po.yumdb_info.from_repo_timestamp = str(md.timestamp)
  
@@ -151121,7 +151424,7 @@ index 99039e0..3680356 100644
                  loginuid = misc.getloginuid()
                  if txmbr.updates or txmbr.downgrades or txmbr.reinstall:
                      if txmbr.updates:
-@@ -1640,11 +1815,16 @@ class YumBase(depsolve.Depsolve):
+@@ -1640,11 +1825,16 @@ class YumBase(depsolve.Depsolve):
                          opo = po
                      if 'installed_by' in opo.yumdb_info:
                          po.yumdb_info.installed_by = opo.yumdb_info.installed_by
@@ -151138,7 +151441,7 @@ index 99039e0..3680356 100644
          # Remove old ones after installing new ones, so we can copy values.
          for txmbr in self.tsInfo:
              if txmbr.output_state in TS_INSTALL_STATES:
-@@ -1662,10 +1842,13 @@ class YumBase(depsolve.Depsolve):
+@@ -1662,10 +1852,13 @@ class YumBase(depsolve.Depsolve):
                                                 ' but is not!' % txmbr.po))
                          # Note: Get Panu to do te.Failed() so we don't have to
                          txmbr.output_state = TS_FAILED
@@ -151152,7 +151455,7 @@ index 99039e0..3680356 100644
                  self.verbose_logger.log(logginglevels.DEBUG_2, 'What is this? %s' % txmbr.po)
  
          self.plugins.run('postverifytrans')
-@@ -1680,10 +1863,11 @@ class YumBase(depsolve.Depsolve):
+@@ -1680,10 +1873,11 @@ class YumBase(depsolve.Depsolve):
          self.verbose_logger.debug('VerifyTransaction time: %0.3f' % (time.time() - vt_st))
  
      def costExcludePackages(self):
@@ -151168,7 +151471,7 @@ index 99039e0..3680356 100644
          # if all the repo.costs are equal then don't bother running things
          costs = {}
          for r in self.repos.listEnabled():
-@@ -1705,10 +1889,12 @@ class YumBase(depsolve.Depsolve):
+@@ -1705,10 +1899,12 @@ class YumBase(depsolve.Depsolve):
              done = True
  
      def excludePackages(self, repo=None):
@@ -151184,7 +151487,7 @@ index 99039e0..3680356 100644
          if "all" in self.conf.disable_excludes:
              return
          
-@@ -1735,9 +1921,11 @@ class YumBase(depsolve.Depsolve):
+@@ -1735,9 +1931,11 @@ class YumBase(depsolve.Depsolve):
              self.pkgSack.addPackageExcluder(repoid, exid,'exclude.match', match)
  
      def includePackages(self, repo):
@@ -151199,7 +151502,7 @@ index 99039e0..3680356 100644
          includelist = repo.getIncludePkgList()
          
          if len(includelist) == 0:
-@@ -1757,8 +1945,11 @@ class YumBase(depsolve.Depsolve):
+@@ -1757,8 +1955,11 @@ class YumBase(depsolve.Depsolve):
          self.pkgSack.addPackageExcluder(repo.id, exid, 'exclude.marked')
          
      def doLock(self, lockfile = YUM_PID_FILE):
@@ -151213,7 +151516,7 @@ index 99039e0..3680356 100644
          if self.conf.uid != 0:
              #  If we are a user, assume we are using the root cache ... so don't
              # bother locking.
-@@ -1774,38 +1965,26 @@ class YumBase(depsolve.Depsolve):
+@@ -1774,38 +1975,26 @@ class YumBase(depsolve.Depsolve):
          
          mypid=str(os.getpid())    
          while not self._lock(lockfile, mypid, 0644):
@@ -151267,7 +151570,7 @@ index 99039e0..3680356 100644
          # if we're not root then we don't lock - just return nicely
          #  Note that we can get here from __del__, so if we haven't created
          # YumBase.conf we don't want to do so here as creating stuff inside
-@@ -1830,31 +2009,69 @@ class YumBase(depsolve.Depsolve):
+@@ -1830,31 +2019,69 @@ class YumBase(depsolve.Depsolve):
          self._unlock(lockfile)
          self._lockfile = None
          
@@ -151347,7 +151650,7 @@ index 99039e0..3680356 100644
          failed = False
  
          if type(fo) is types.InstanceType:
-@@ -1894,9 +2111,16 @@ class YumBase(depsolve.Depsolve):
+@@ -1894,9 +2121,16 @@ class YumBase(depsolve.Depsolve):
          
          
      def verifyChecksum(self, fo, checksumType, csum):
@@ -151367,7 +151670,7 @@ index 99039e0..3680356 100644
          try:
              filesum = misc.checksum(checksumType, fo)
          except Errors.MiscError, e:
-@@ -1908,6 +2132,17 @@ class YumBase(depsolve.Depsolve):
+@@ -1908,6 +2142,17 @@ class YumBase(depsolve.Depsolve):
          return 0
  
      def downloadPkgs(self, pkglist, callback=None, callback_total=None):
@@ -151385,10 +151688,28 @@ index 99039e0..3680356 100644
          def mediasort(apo, bpo):
              # FIXME: we should probably also use the mediaid; else we
              # could conceivably ping-pong between different disc1's
-@@ -1998,16 +2233,6 @@ class YumBase(depsolve.Depsolve):
+@@ -1979,8 +2224,9 @@ class YumBase(depsolve.Depsolve):
+             urlgrabber.progress.text_meter_total_size(remote_size)
+         beg_download = time.time()
+         i = 0
+-        local_size = 0
++        local_size = [0]
+         done_repos = set()
++        async = hasattr(urlgrabber.grabber, 'parallel_wait')
+         for po in remote_pkgs:
+             #  Recheck if the file is there, works around a couple of weird
+             # edge cases.
+@@ -1992,52 +2238,47 @@ class YumBase(depsolve.Depsolve):
+                     remote_size -= po.size
+                     if hasattr(urlgrabber.progress, 'text_meter_total_size'):
+                         urlgrabber.progress.text_meter_total_size(remote_size,
+-                                                                  local_size)
++                                                                  local_size[0])
+                     continue
+                 if os.path.getsize(local) >= po.size:
                      os.unlink(local)
  
-             checkfunc = (self.verifyPkg, (po, 1), {})
+-            checkfunc = (self.verifyPkg, (po, 1), {})
 -            dirstat = os.statvfs(po.repo.pkgdir)
 -            if (dirstat.f_bavail * dirstat.f_bsize) <= long(po.size):
 -                adderror(po, _('Insufficient space in download directory %s\n'
@@ -151399,19 +151720,65 @@ index 99039e0..3680356 100644
 -                          format_number(po.size)))
 -                continue
 -            
-             try:
-                 if i == 1 and not local_size and remote_size == po.size:
-                     text = os.path.basename(po.relativepath)
-@@ -2032,7 +2257,7 @@ class YumBase(depsolve.Depsolve):
-                 done_repos.add(po.repoid)
- 
-             except Errors.RepoError, e:
+-            try:
+-                if i == 1 and not local_size and remote_size == po.size:
+-                    text = os.path.basename(po.relativepath)
+-                else:
+-                    text = '(%s/%s): %s' % (i, len(remote_pkgs),
+-                                            os.path.basename(po.relativepath))
+-                mylocal = po.repo.getPackage(po,
+-                                   checkfunc=checkfunc,
+-                                   text=text,
+-                                   cache=po.repo.http_caching != 'none',
+-                                   )
+-                local_size += po.size
++            def checkfunc(obj, po=po):
++                self.verifyPkg(obj, po, 1)
++                local_size[0] += po.size
+                 if hasattr(urlgrabber.progress, 'text_meter_total_size'):
+                     urlgrabber.progress.text_meter_total_size(remote_size,
+-                                                              local_size)
++                                                              local_size[0])
+                 if po.repoid not in done_repos:
++                    done_repos.add(po.repoid)
+                     #  Check a single package per. repo. ... to give a hint to
+                     # the user on big downloads.
+                     result, errmsg = self.sigCheckPkg(po)
+                     if result != 0:
+                         self.verbose_logger.warn("%s", errmsg)
+-                done_repos.add(po.repoid)
+-
+-            except Errors.RepoError, e:
 -                adderror(po, str(e))
-+                adderror(po, exception2msg(e))
-             else:
-                 po.localpath = mylocal
+-            else:
+-                po.localpath = mylocal
++                po.localpath = obj.filename
                  if po in errors:
-@@ -2052,7 +2277,22 @@ class YumBase(depsolve.Depsolve):
+                     del errors[po]
+ 
++            text = os.path.basename(po.relativepath)
++            kwargs = {}
++            if async and po.repo._async:
++                kwargs['failfunc'] = lambda obj, po=po: adderror(po, exception2msg(obj.exception))
++                kwargs['async'] = True
++            elif not (i == 1 and not local_size[0] and remote_size == po.size):
++                text = '(%s/%s): %s' % (i, len(remote_pkgs), text)
++            try:
++                po.repo.getPackage(po,
++                                   checkfunc=checkfunc,
++                                   text=text,
++                                   cache=po.repo.http_caching != 'none',
++                                   **kwargs
++                                   )
++            except Errors.RepoError, e:
++                adderror(po, exception2msg(e))
++        if async:
++            urlgrabber.grabber.parallel_wait()
++
+         if hasattr(urlgrabber.progress, 'text_meter_total_size'):
+             urlgrabber.progress.text_meter_total_size(0)
+         if callback_total is not None and not errors:
+@@ -2052,7 +2293,22 @@ class YumBase(depsolve.Depsolve):
          return errors
  
      def verifyHeader(self, fo, po, raiseError):
@@ -151435,7 +151802,7 @@ index 99039e0..3680356 100644
          if type(fo) is types.InstanceType:
              fo = fo.filename
              
-@@ -2076,9 +2316,12 @@ class YumBase(depsolve.Depsolve):
+@@ -2076,9 +2332,12 @@ class YumBase(depsolve.Depsolve):
          return 1
          
      def downloadHeader(self, po):
@@ -151450,7 +151817,7 @@ index 99039e0..3680356 100644
          if hasattr(po, 'pkgtype') and po.pkgtype == 'local':
              return
                  
-@@ -2122,15 +2365,17 @@ class YumBase(depsolve.Depsolve):
+@@ -2122,15 +2381,17 @@ class YumBase(depsolve.Depsolve):
              return
  
      def sigCheckPkg(self, po):
@@ -151476,7 +151843,7 @@ index 99039e0..3680356 100644
          if self._override_sigchecks:
              check = False
              hasgpgkey = 0
-@@ -2181,6 +2426,9 @@ class YumBase(depsolve.Depsolve):
+@@ -2181,6 +2442,9 @@ class YumBase(depsolve.Depsolve):
          return result, msg
  
      def cleanUsedHeadersPackages(self):
@@ -151486,7 +151853,7 @@ index 99039e0..3680356 100644
          filelist = []
          for txmbr in self.tsInfo:
              if txmbr.po.state not in TS_INSTALL_STATES:
-@@ -2218,27 +2466,42 @@ class YumBase(depsolve.Depsolve):
+@@ -2218,27 +2482,42 @@ class YumBase(depsolve.Depsolve):
                      _('%s removed'), fn)
          
      def cleanHeaders(self):
@@ -151531,7 +151898,7 @@ index 99039e0..3680356 100644
          cachedir = self.conf.persistdir + "/rpmdb-indexes/"
          if not os.path.exists(cachedir):
              filelist = []
-@@ -2272,8 +2535,29 @@ class YumBase(depsolve.Depsolve):
+@@ -2272,8 +2551,29 @@ class YumBase(depsolve.Depsolve):
  
      def doPackageLists(self, pkgnarrow='all', patterns=None, showdups=None,
                         ignore_case=False):
@@ -151563,7 +151930,7 @@ index 99039e0..3680356 100644
          if showdups is None:
              showdups = self.conf.showdupesfromrepos
          ygh = misc.GenericHolder(iter=pkgnarrow)
-@@ -2323,10 +2607,22 @@ class YumBase(depsolve.Depsolve):
+@@ -2323,10 +2623,22 @@ class YumBase(depsolve.Depsolve):
                      key = (pkg.name, pkg.arch)
                      if pkg.pkgtup in dinst:
                          reinstall_available.append(pkg)
@@ -151589,7 +151956,7 @@ index 99039e0..3680356 100644
  
          # produce the updates list of tuples
          elif pkgnarrow == 'updates':
-@@ -2461,14 +2757,13 @@ class YumBase(depsolve.Depsolve):
+@@ -2461,14 +2773,13 @@ class YumBase(depsolve.Depsolve):
  
          
      def findDeps(self, pkgs):
@@ -151609,7 +151976,7 @@ index 99039e0..3680356 100644
          results = {}
  
          for pkg in pkgs:
-@@ -2495,10 +2790,22 @@ class YumBase(depsolve.Depsolve):
+@@ -2495,10 +2806,22 @@ class YumBase(depsolve.Depsolve):
      # pre 3.2.10 API used to always showdups, so that's the default atm.
      def searchGenerator(self, fields, criteria, showdups=True, keys=False, 
                                               searchtags=True, searchrpmdb=True):
@@ -151636,7 +152003,7 @@ index 99039e0..3680356 100644
          sql_fields = []
          for f in fields:
              sql_fields.append(RPM_TO_SQLITE.get(f, f))
-@@ -2661,6 +2968,14 @@ class YumBase(depsolve.Depsolve):
+@@ -2661,6 +2984,14 @@ class YumBase(depsolve.Depsolve):
                      yield (po, vs)
  
      def searchPackageTags(self, criteria):
@@ -151651,7 +152018,7 @@ index 99039e0..3680356 100644
          results = {} # name = [(criteria, taglist)]
          for c in criteria:
              c = c.lower()
-@@ -2677,11 +2992,16 @@ class YumBase(depsolve.Depsolve):
+@@ -2677,11 +3008,16 @@ class YumBase(depsolve.Depsolve):
          return results
          
      def searchPackages(self, fields, criteria, callback=None):
@@ -151673,7 +152040,7 @@ index 99039e0..3680356 100644
          warnings.warn(_('searchPackages() will go away in a future version of Yum.\
                        Use searchGenerator() instead. \n'),
                  Errors.YumFutureDeprecationWarning, stacklevel=2)           
-@@ -2700,6 +3020,19 @@ class YumBase(depsolve.Depsolve):
+@@ -2700,13 +3036,23 @@ class YumBase(depsolve.Depsolve):
      
      def searchPackageProvides(self, args, callback=None,
                                callback_has_matchfor=False):
@@ -151693,7 +152060,15 @@ index 99039e0..3680356 100644
          def _arg_data(arg):
              if not misc.re_glob(arg):
                  isglob = False
-@@ -2723,7 +3056,7 @@ class YumBase(depsolve.Depsolve):
+-                if arg[0] != '/':
+-                    canBeFile = False
+-                else:
+-                    canBeFile = True
++                canBeFile = arg.startswith('/')
+             else:
+                 isglob = True
+                 canBeFile = misc.re_filename(arg)
+@@ -2723,7 +3069,7 @@ class YumBase(depsolve.Depsolve):
                  where = self.returnPackagesByDep(arg)
              else:
                  usedDepString = False
@@ -151702,7 +152077,7 @@ index 99039e0..3680356 100644
              self.verbose_logger.log(logginglevels.DEBUG_1,
                 P_('Searching %d package', 'Searching %d packages', len(where)), len(where))
              
-@@ -2817,25 +3150,93 @@ class YumBase(depsolve.Depsolve):
+@@ -2817,25 +3163,93 @@ class YumBase(depsolve.Depsolve):
              
          return matches
  
@@ -151807,7 +152182,7 @@ index 99039e0..3680356 100644
                  if uservisible:
                      if grp.user_visible:
                          installed.append(grp)
-@@ -2848,12 +3249,29 @@ class YumBase(depsolve.Depsolve):
+@@ -2848,12 +3262,29 @@ class YumBase(depsolve.Depsolve):
                  else:
                      available.append(grp)
              
@@ -151840,7 +152215,7 @@ index 99039e0..3680356 100644
          txmbrs_used = []
          
          thesegroups = self.comps.return_groups(grpid)
-@@ -2861,20 +3279,28 @@ class YumBase(depsolve.Depsolve):
+@@ -2861,20 +3292,28 @@ class YumBase(depsolve.Depsolve):
              raise Errors.GroupsError, _("No Group named %s exists") % to_unicode(grpid)
  
          for thisgroup in thesegroups:
@@ -151871,7 +152246,7 @@ index 99039e0..3680356 100644
          thesegroups = self.comps.return_groups(grpid)
          if not thesegroups:
              raise Errors.GroupsError, _("No Group named %s exists") % to_unicode(grpid)
-@@ -2898,13 +3324,18 @@ class YumBase(depsolve.Depsolve):
+@@ -2898,13 +3337,18 @@ class YumBase(depsolve.Depsolve):
                              self.tsInfo.remove(txmbr.po.pkgtup)
          
          
@@ -151897,7 +152272,7 @@ index 99039e0..3680356 100644
          """
  
          if not self.comps.has_group(grpid):
-@@ -2934,12 +3365,47 @@ class YumBase(depsolve.Depsolve):
+@@ -2934,12 +3378,47 @@ class YumBase(depsolve.Depsolve):
              if 'optional' in package_types:
                  pkgs.extend(thisgroup.optional_packages)
  
@@ -151946,7 +152321,7 @@ index 99039e0..3680356 100644
                  except Errors.InstallError, e:
                      self.verbose_logger.debug(_('No package named %s available to be installed'),
                          pkg)
-@@ -2953,6 +3419,7 @@ class YumBase(depsolve.Depsolve):
+@@ -2953,6 +3432,7 @@ class YumBase(depsolve.Depsolve):
                  group_conditionals = enable_group_conditionals
  
              count_cond_test = 0
@@ -151954,7 +152329,7 @@ index 99039e0..3680356 100644
              if group_conditionals:
                  for condreq, cond in thisgroup.conditional_packages.iteritems():
                      if self.isPackageInstalled(cond):
-@@ -2997,10 +3464,14 @@ class YumBase(depsolve.Depsolve):
+@@ -2997,10 +3477,14 @@ class YumBase(depsolve.Depsolve):
          return txmbrs_used
  
      def deselectGroup(self, grpid, force=False):
@@ -151973,7 +152348,7 @@ index 99039e0..3680356 100644
          
          if not self.comps.has_group(grpid):
              raise Errors.GroupsError, _("No Group named %s exists") % to_unicode(grpid)
-@@ -3035,12 +3506,21 @@ class YumBase(depsolve.Depsolve):
+@@ -3035,12 +3519,21 @@ class YumBase(depsolve.Depsolve):
                              self.tsInfo.remove(pkg.pkgtup)
          
      def getPackageObject(self, pkgtup, allow_missing=False):
@@ -152001,7 +152376,7 @@ index 99039e0..3680356 100644
          # look it up in the self.localPackages first:
          for po in self.localPackages:
              if po.pkgtup == pkgtup:
-@@ -3049,7 +3529,7 @@ class YumBase(depsolve.Depsolve):
+@@ -3049,7 +3542,7 @@ class YumBase(depsolve.Depsolve):
          pkgs = self.pkgSack.searchPkgTuple(pkgtup)
  
          if len(pkgs) == 0:
@@ -152010,7 +152385,7 @@ index 99039e0..3680356 100644
              if allow_missing: #  This can happen due to excludes after .up has
                  return None   # happened.
              raise Errors.DepError, _('Package tuple %s could not be found in packagesack') % str(pkgtup)
-@@ -3065,13 +3545,21 @@ class YumBase(depsolve.Depsolve):
+@@ -3065,13 +3558,21 @@ class YumBase(depsolve.Depsolve):
          return result
  
      def getInstalledPackageObject(self, pkgtup):
@@ -152037,7 +152412,7 @@ index 99039e0..3680356 100644
              raise Errors.RpmDBError, _('Package tuple %s could not be found in rpmdb') % str(pkgtup)
  
          # Dito. FIXME from getPackageObject() for len() > 1 ... :)
-@@ -3079,9 +3567,11 @@ class YumBase(depsolve.Depsolve):
+@@ -3079,9 +3580,11 @@ class YumBase(depsolve.Depsolve):
          return po
          
      def gpgKeyCheck(self):
@@ -152051,7 +152426,7 @@ index 99039e0..3680356 100644
          gpgkeyschecked = self.conf.cachedir + '/.gpgkeyschecked.yum'
          if os.path.exists(gpgkeyschecked):
              return 1
-@@ -3106,9 +3596,13 @@ class YumBase(depsolve.Depsolve):
+@@ -3106,9 +3609,13 @@ class YumBase(depsolve.Depsolve):
              return 1
  
      def returnPackagesByDep(self, depstring):
@@ -152067,7 +152442,7 @@ index 99039e0..3680356 100644
          if not depstring:
              return []
  
-@@ -3135,9 +3629,16 @@ class YumBase(depsolve.Depsolve):
+@@ -3135,9 +3642,16 @@ class YumBase(depsolve.Depsolve):
          return self.pkgSack.getProvides(depname, depflags, depver).keys()
  
      def returnPackageByDep(self, depstring):
@@ -152087,7 +152462,7 @@ index 99039e0..3680356 100644
          # we get all sorts of randomness here
          errstring = depstring
          if type(depstring) not in types.StringTypes:
-@@ -3149,16 +3650,22 @@ class YumBase(depsolve.Depsolve):
+@@ -3149,16 +3663,22 @@ class YumBase(depsolve.Depsolve):
              raise Errors.YumBaseError, _('No Package found for %s') % errstring
          
          ps = ListPackageSack(pkglist)
@@ -152114,7 +152489,7 @@ index 99039e0..3680356 100644
          if not depstring:
              return []
  
-@@ -3184,12 +3691,47 @@ class YumBase(depsolve.Depsolve):
+@@ -3184,12 +3704,47 @@ class YumBase(depsolve.Depsolve):
  
          return self.rpmdb.getProvides(depname, depflags, depver).keys()
  
@@ -152164,7 +152539,7 @@ index 99039e0..3680356 100644
          
          
          if len(pkglist) == 0:
-@@ -3198,14 +3740,23 @@ class YumBase(depsolve.Depsolve):
+@@ -3198,14 +3753,23 @@ class YumBase(depsolve.Depsolve):
          if len(pkglist) == 1:
              return pkglist[0]
  
@@ -152194,7 +152569,7 @@ index 99039e0..3680356 100644
          returnlist = []
          compatArchList = self.arch.get_arch_list(arch)
          multiLib = []
-@@ -3222,9 +3773,9 @@ class YumBase(depsolve.Depsolve):
+@@ -3222,9 +3786,9 @@ class YumBase(depsolve.Depsolve):
                  singleLib.append(po)
                  
          # we now have three lists.  find the best package(s) of each
@@ -152207,7 +152582,7 @@ index 99039e0..3680356 100644
  
          if single_name and multi and single and multi.name != single.name:
              # Sinlge _must_ match multi, if we want a single package name
-@@ -3238,7 +3789,7 @@ class YumBase(depsolve.Depsolve):
+@@ -3238,7 +3802,7 @@ class YumBase(depsolve.Depsolve):
          # if there's a noarch and it's newer than the multilib, we want
          # just the noarch.  otherwise, we want multi + single
          elif multi:
@@ -152216,7 +152591,7 @@ index 99039e0..3680356 100644
              if best.arch == "noarch":
                  returnlist.append(no)
              else:
-@@ -3246,7 +3797,7 @@ class YumBase(depsolve.Depsolve):
+@@ -3246,7 +3810,7 @@ class YumBase(depsolve.Depsolve):
                  if single: returnlist.append(single)
          # similar for the non-multilib case
          elif single:
@@ -152225,7 +152600,7 @@ index 99039e0..3680356 100644
              if best.arch == "noarch":
                  returnlist.append(no)
              else:
-@@ -3350,23 +3901,27 @@ class YumBase(depsolve.Depsolve):
+@@ -3350,23 +3914,27 @@ class YumBase(depsolve.Depsolve):
              done = True
  
              slow = next_func(slow)
@@ -152258,7 +152633,7 @@ index 99039e0..3680356 100644
      def _at_groupremove(self, pattern):
          " Do groupremove via. leading @ on the cmd line, for remove."
          assert pattern[0] == '@'
-@@ -3398,7 +3953,7 @@ class YumBase(depsolve.Depsolve):
+@@ -3398,7 +3966,7 @@ class YumBase(depsolve.Depsolve):
      def _minus_deselect(self, pattern):
          """ Remove things from the transaction, like kickstart. """
          assert pattern[0] == '-'
@@ -152267,7 +152642,7 @@ index 99039e0..3680356 100644
  
          if pat and pat[0] == '@':
              pat = pat[1:]
-@@ -3437,14 +3992,61 @@ class YumBase(depsolve.Depsolve):
+@@ -3437,14 +4005,61 @@ class YumBase(depsolve.Depsolve):
              if flag not in self.tsInfo.probFilterFlags:
                  self.tsInfo.probFilterFlags.append(flag)
  
@@ -152335,7 +152710,7 @@ index 99039e0..3680356 100644
          pkgs = []
          was_pattern = False
          if po:
-@@ -3477,20 +4079,12 @@ class YumBase(depsolve.Depsolve):
+@@ -3477,20 +4092,12 @@ class YumBase(depsolve.Depsolve):
                      self.verbose_logger.debug(_('Checking for virtual provide or file-provide for %s'), 
                          arg)
  
@@ -152362,7 +152737,7 @@ index 99039e0..3680356 100644
              else:
                  nevra_dict = self._nevra_kwarg_parse(kwargs)
  
-@@ -3577,8 +4171,8 @@ class YumBase(depsolve.Depsolve):
+@@ -3577,8 +4184,8 @@ class YumBase(depsolve.Depsolve):
                      continue
              
              # make sure this shouldn't be passed to update:
@@ -152373,7 +152748,7 @@ index 99039e0..3680356 100644
                  txmbrs = self.update(po=po)
                  tx_return.extend(txmbrs)
                  continue
-@@ -3587,7 +4181,7 @@ class YumBase(depsolve.Depsolve):
+@@ -3587,7 +4194,7 @@ class YumBase(depsolve.Depsolve):
              # something else in the repo. Unless there is a obsoletion loop,
              # at which point ignore everything.
              obsoleting_pkg = None
@@ -152382,7 +152757,7 @@ index 99039e0..3680356 100644
                  obsoleting_pkg = self._test_loop(po, self._pkg2obspkg)
              if obsoleting_pkg is not None:
                  # this is not a definitive check but it'll make sure we don't
-@@ -3600,23 +4194,23 @@ class YumBase(depsolve.Depsolve):
+@@ -3600,23 +4207,23 @@ class YumBase(depsolve.Depsolve):
                      already_obs = pkgs[0]
  
                  if already_obs:
@@ -152413,7 +152788,7 @@ index 99039e0..3680356 100644
                      continue
  
              # make sure we don't have a name.arch of this already installed
-@@ -3630,7 +4224,7 @@ class YumBase(depsolve.Depsolve):
+@@ -3630,7 +4237,7 @@ class YumBase(depsolve.Depsolve):
                          found = True
                          break
                  if not found:
@@ -152422,7 +152797,7 @@ index 99039e0..3680356 100644
                      txmbrs = self.update(po=po)
                      tx_return.extend(txmbrs)
                      continue
-@@ -3719,14 +4313,33 @@ class YumBase(depsolve.Depsolve):
+@@ -3719,14 +4326,33 @@ class YumBase(depsolve.Depsolve):
          return txmbr
  
      def update(self, po=None, requiringPo=None, update_to=False, **kwargs):
@@ -152463,7 +152838,7 @@ index 99039e0..3680356 100644
          # check for args - if no po nor kwargs, do them all
          # if po, do it, ignore all else
          # if no po do kwargs
-@@ -3765,7 +4378,12 @@ class YumBase(depsolve.Depsolve):
+@@ -3765,7 +4391,12 @@ class YumBase(depsolve.Depsolve):
                      if new is None:
                          continue
                      tx_return.extend(self.update(po=new))
@@ -152477,7 +152852,7 @@ index 99039e0..3680356 100644
              return tx_return
  
          # complications
-@@ -3787,7 +4405,7 @@ class YumBase(depsolve.Depsolve):
+@@ -3787,7 +4418,7 @@ class YumBase(depsolve.Depsolve):
                  return self._minus_deselect(kwargs['pattern'])
  
              if kwargs['pattern'] and kwargs['pattern'][0] == '@':
@@ -152486,7 +152861,7 @@ index 99039e0..3680356 100644
  
              arg = kwargs['pattern']
              if not update_to:
-@@ -3920,6 +4538,18 @@ class YumBase(depsolve.Depsolve):
+@@ -3920,6 +4551,18 @@ class YumBase(depsolve.Depsolve):
                      tx_return.append(txmbr)
                          
          for available_pkg in availpkgs:
@@ -152505,7 +152880,7 @@ index 99039e0..3680356 100644
              #  Make sure we're not installing a package which is obsoleted by
              # something else in the repo. Unless there is a obsoletion loop,
              # at which point ignore everything.
-@@ -3985,11 +4615,18 @@ class YumBase(depsolve.Depsolve):
+@@ -3985,11 +4628,18 @@ class YumBase(depsolve.Depsolve):
          return tx_return
          
      def remove(self, po=None, **kwargs):
@@ -152529,7 +152904,7 @@ index 99039e0..3680356 100644
          if not po and not kwargs:
              raise Errors.RemoveError, 'Nothing specified to remove'
          
-@@ -4055,17 +4692,19 @@ class YumBase(depsolve.Depsolve):
+@@ -4055,17 +4705,19 @@ class YumBase(depsolve.Depsolve):
          return tx_return
  
      def installLocal(self, pkg, po=None, updateonly=False):
@@ -152559,7 +152934,7 @@ index 99039e0..3680356 100644
          # read in the package into a YumLocalPackage Object
          # append it to self.localPackages
          # check if it can be installed or updated based on nevra versus rpmdb
-@@ -4183,16 +4822,15 @@ class YumBase(depsolve.Depsolve):
+@@ -4183,16 +4835,15 @@ class YumBase(depsolve.Depsolve):
          return tx_return
  
      def reinstallLocal(self, pkg, po=None):
@@ -152584,7 +152959,7 @@ index 99039e0..3680356 100644
          if not po:
              try:
                  po = YumUrlPackage(self, ts=self.rpmdb.readOnlyTS(), url=pkg,
-@@ -4215,9 +4853,19 @@ class YumBase(depsolve.Depsolve):
+@@ -4215,9 +4866,19 @@ class YumBase(depsolve.Depsolve):
          return self.reinstall(po=po)
  
      def reinstall(self, po=None, **kwargs):
@@ -152607,7 +152982,7 @@ index 99039e0..3680356 100644
          self._add_prob_flags(rpm.RPMPROB_FILTER_REPLACEPKG,
                               rpm.RPMPROB_FILTER_REPLACENEWFILES,
                               rpm.RPMPROB_FILTER_REPLACEOLDFILES)
-@@ -4259,16 +4907,15 @@ class YumBase(depsolve.Depsolve):
+@@ -4259,16 +4920,15 @@ class YumBase(depsolve.Depsolve):
          return tx_mbrs
          
      def downgradeLocal(self, pkg, po=None):
@@ -152632,7 +153007,7 @@ index 99039e0..3680356 100644
          if not po:
              try:
                  po = YumUrlPackage(self, ts=self.rpmdb.readOnlyTS(), url=pkg,
-@@ -4309,13 +4956,19 @@ class YumBase(depsolve.Depsolve):
+@@ -4309,13 +4969,19 @@ class YumBase(depsolve.Depsolve):
          return False
          
      def downgrade(self, po=None, **kwargs):
@@ -152659,7 +153034,17 @@ index 99039e0..3680356 100644
          if not po and not kwargs:
              raise Errors.DowngradeError, 'Nothing specified to downgrade'
  
-@@ -4457,7 +5110,7 @@ class YumBase(depsolve.Depsolve):
+@@ -4421,6 +5087,9 @@ class YumBase(depsolve.Depsolve):
+                 warned_nas.add(na)
+                 continue
+ 
++            if pkg.verEQ(lipkg):
++                continue
++
+             if pkg.verGE(lipkg):
+                 if na not in warned_nas:
+                     msg = _('Only Upgrade available on package: %s') % pkg
+@@ -4457,7 +5126,7 @@ class YumBase(depsolve.Depsolve):
          if e and v and r:
              evr = '%s:%s-%s' % (e, v, r)
          elif v and r:
@@ -152668,7 +153053,7 @@ index 99039e0..3680356 100644
          elif e and v:
              evr = '%s:%s' % (e, v)
          elif v: # e and r etc. is just too weird to print
-@@ -4500,12 +5153,24 @@ class YumBase(depsolve.Depsolve):
+@@ -4500,12 +5169,24 @@ class YumBase(depsolve.Depsolve):
  
          return returndict
  
@@ -152696,7 +153081,7 @@ index 99039e0..3680356 100644
          old_conf_obs = self.conf.obsoletes
          self.conf.obsoletes = False
          done = False
-@@ -4515,19 +5180,46 @@ class YumBase(depsolve.Depsolve):
+@@ -4515,19 +5196,46 @@ class YumBase(depsolve.Depsolve):
                      done = True
          for pkg in transaction.trans_data:
              if pkg.state == 'Downgrade':
@@ -152743,7 +153128,7 @@ index 99039e0..3680356 100644
                  if self.install(pkgtup=pkg.pkgtup):
                      done = True
          for pkg in transaction.trans_data:
-@@ -4538,8 +5230,14 @@ class YumBase(depsolve.Depsolve):
+@@ -4538,8 +5246,14 @@ class YumBase(depsolve.Depsolve):
          return done
  
      def history_undo(self, transaction):
@@ -152760,7 +153145,25 @@ index 99039e0..3680356 100644
          # NOTE: This is somewhat basic atm. ... for instance we don't check
          #       that we are going from the old new version. However it's still
          #       better than the RHN rollback code, and people pay for that :).
-@@ -4674,39 +5372,49 @@ class YumBase(depsolve.Depsolve):
+@@ -4616,7 +5330,7 @@ class YumBase(depsolve.Depsolve):
+ 
+         except urlgrabber.grabber.URLGrabError, e:
+             raise Errors.YumBaseError(_('GPG key retrieval failed: ') +
+-                                      to_unicode(str(e)))
++                                      exception2msg(e))
+                                       
+         # check for a .asc file accompanying it - that's our gpg sig on the key
+         # suck it down and do the check
+@@ -4649,7 +5363,7 @@ class YumBase(depsolve.Depsolve):
+             keys_info = misc.getgpgkeyinfo(rawkey, multiple=True)
+         except ValueError, e:
+             raise Errors.YumBaseError(_('Invalid GPG Key from %s: %s') % 
+-                                      (url, to_unicode(str(e))))
++                                      (url, exception2msg(e)))
+         keys = []
+         for keyinfo in keys_info:
+             thiskey = {}
+@@ -4674,39 +5388,49 @@ class YumBase(depsolve.Depsolve):
              if pkgs:
                  pkgs = sorted(pkgs)[-1]
                  msg = (_('Importing %s key 0x%s:\n'
@@ -152828,7 +153231,7 @@ index 99039e0..3680356 100644
          user_cb_fail = False
          for keyurl in keyurls:
              keys = self._retrievePublicKey(keyurl, repo)
-@@ -4725,7 +5433,9 @@ class YumBase(depsolve.Depsolve):
+@@ -4725,7 +5449,9 @@ class YumBase(depsolve.Depsolve):
                      # Try installing/updating GPG key
                      self._getKeyImportMessage(info, keyurl)
                      rc = False
@@ -152839,7 +153242,7 @@ index 99039e0..3680356 100644
                          rc = True
                          
                      # grab the .sig/.asc for the keyurl, if it exists
-@@ -4751,8 +5461,8 @@ class YumBase(depsolve.Depsolve):
+@@ -4751,8 +5477,8 @@ class YumBase(depsolve.Depsolve):
                  ts = self.rpmdb.readOnlyTS()
                  result = ts.pgpImportPubkey(misc.procgpgkey(info['raw_key']))
                  if result != 0:
@@ -152850,7 +153253,7 @@ index 99039e0..3680356 100644
                  self.logger.info(_('Key imported successfully'))
                  key_installed = True
  
-@@ -4760,18 +5470,20 @@ class YumBase(depsolve.Depsolve):
+@@ -4760,18 +5486,20 @@ class YumBase(depsolve.Depsolve):
              raise Errors.YumBaseError, _("Didn't install any keys")
  
          if not key_installed:
@@ -152876,7 +153279,7 @@ index 99039e0..3680356 100644
      
      def _getAnyKeyForRepo(self, repo, destdir, keyurl_list, is_cakey=False, callback=None):
          """
-@@ -4788,6 +5500,18 @@ class YumBase(depsolve.Depsolve):
+@@ -4788,6 +5516,18 @@ class YumBase(depsolve.Depsolve):
          """
  
          key_installed = False
@@ -152895,7 +153298,7 @@ index 99039e0..3680356 100644
          user_cb_fail = False
          for keyurl in keyurl_list:
              keys = self._retrievePublicKey(keyurl, repo, getSig=not is_cakey)
-@@ -4819,8 +5543,11 @@ class YumBase(depsolve.Depsolve):
+@@ -4819,8 +5559,11 @@ class YumBase(depsolve.Depsolve):
                  if not key_installed:
                      self._getKeyImportMessage(info, keyurl, keytype)
                      rc = False
@@ -152908,7 +153311,7 @@ index 99039e0..3680356 100644
                      elif callback:
                          rc = callback({"repo": repo, "userid": info['userid'],
                                          "hexkeyid": info['hexkeyid'], "keyurl": keyurl,
-@@ -4835,7 +5562,8 @@ class YumBase(depsolve.Depsolve):
+@@ -4835,7 +5578,8 @@ class YumBase(depsolve.Depsolve):
                  # Import the key
                  result = misc.import_key_to_pubring(info['raw_key'], info['hexkeyid'], gpgdir=destdir)
                  if not result:
@@ -152918,7 +153321,7 @@ index 99039e0..3680356 100644
                  self.logger.info(_('Key imported successfully'))
                  key_installed = True
                  # write out the key id to imported_cakeys in the repos basedir
-@@ -4851,36 +5579,35 @@ class YumBase(depsolve.Depsolve):
+@@ -4851,36 +5595,35 @@ class YumBase(depsolve.Depsolve):
                              pass
  
          if not key_installed and user_cb_fail:
@@ -152971,7 +153374,41 @@ index 99039e0..3680356 100644
          self._getAnyKeyForRepo(repo, repo.gpgcadir, repo.gpgcakey, is_cakey=True, callback=callback)
  
      def _limit_installonly_pkgs(self):
-@@ -4959,19 +5686,22 @@ class YumBase(depsolve.Depsolve):
+@@ -4927,6 +5670,7 @@ class YumBase(depsolve.Depsolve):
+         ts = self.rpmdb.readOnlyTS()
+         (cur_kernel_v, cur_kernel_r) = misc.get_running_kernel_version_release(ts)
+         install_only_names = set(self.conf.installonlypkgs)
++        found = {}
+         for m in self.tsInfo.getMembers():
+             if m.ts_state not in ('i', 'u'):
+                 continue
+@@ -4937,12 +5681,21 @@ class YumBase(depsolve.Depsolve):
+             if not po_names.intersection(install_only_names):
+                 continue
+ 
+-            installed = self.rpmdb.searchNevra(name=m.name)
++            if m.name not in found:
++                found[m.name] = 1
++            else:
++                found[m.name] += 1
++
++        for name in found:
++            installed = self.rpmdb.searchNevra(name=name)
+             installed = _sort_and_filter_installonly(installed)
+-            if len(installed) < self.conf.installonly_limit - 1:
+-                continue # we're adding one
+ 
+-            numleft = len(installed) - self.conf.installonly_limit + 1
++            total = len(installed) + found[name]
++            if total <= self.conf.installonly_limit:
++                continue # Not adding enough to trigger.
++
++            # Number left to try and remove...
++            numleft = total - self.conf.installonly_limit
+             for po in installed:
+                 if (po.version, po.release) == (cur_kernel_v, cur_kernel_r): 
+                     # don't remove running
+@@ -4959,19 +5712,22 @@ class YumBase(depsolve.Depsolve):
              txmbr.depends_on.append(rel)
  
      def processTransaction(self, callback=None,rpmTestDisplay=None, rpmDisplay=None):
@@ -153007,7 +153444,7 @@ index 99039e0..3680356 100644
          
          if not callback:
              callback = callbacks.ProcessTransNoOutputCallback()
-@@ -5114,13 +5844,19 @@ class YumBase(depsolve.Depsolve):
+@@ -5114,13 +5870,19 @@ class YumBase(depsolve.Depsolve):
          return results
  
      def add_enable_repo(self, repoid, baseurls=[], mirrorlist=None, **kwargs):
@@ -153034,7 +153471,7 @@ index 99039e0..3680356 100644
          # out of place fixme - maybe we should make this the default repo addition
          # routine and use it from getReposFromConfigFile(), etc.
          newrepo = yumRepo.YumRepository(repoid)
-@@ -5167,9 +5903,15 @@ class YumBase(depsolve.Depsolve):
+@@ -5167,9 +5929,15 @@ class YumBase(depsolve.Depsolve):
  
      def setCacheDir(self, force=False, tmpdir=None, reuse=True,
                      suffix='/$basearch/$releasever'):
@@ -153053,7 +153490,24 @@ index 99039e0..3680356 100644
          if not force and os.geteuid() == 0:
              return True # We are root, not forced, so happy with the global dir.
          if tmpdir is None:
-@@ -5220,13 +5962,24 @@ class YumBase(depsolve.Depsolve):
+@@ -5179,7 +5947,7 @@ class YumBase(depsolve.Depsolve):
+         try:
+             cachedir = misc.getCacheDir(tmpdir, reuse)
+         except (IOError, OSError), e:
+-            self.logger.critical(_('Could not set cachedir: %s') % str(e))
++            self.logger.critical(_('Could not set cachedir: %s') % exception2msg(e))
+             cachedir = None
+             
+         if cachedir is None:
+@@ -5190,6 +5958,7 @@ class YumBase(depsolve.Depsolve):
+             self.prerepoconf.cachedir = cachedir
+         else:
+             self.repos.setCacheDir(cachedir)
++        self._old_cachedir = self.conf.cachedir
+         self.conf.cachedir = cachedir
+         return True # We got a new cache dir
+ 
+@@ -5220,13 +5989,24 @@ class YumBase(depsolve.Depsolve):
          self.history.write_addon_data('config-repos', myrepos)
          
      def verify_plugins_cb(self, verify_package):
@@ -153081,7 +153535,7 @@ index 99039e0..3680356 100644
          if self.tsInfo._unresolvedMembers:
              if auto:
                  self.logger.critical(_("Dependencies not solved. Will not save unresolved transaction."))
-@@ -5234,7 +5987,7 @@ class YumBase(depsolve.Depsolve):
+@@ -5234,7 +6014,7 @@ class YumBase(depsolve.Depsolve):
              raise Errors.YumBaseError(_("Dependencies not solved. Will not save unresolved transaction."))
          
          if not filename:
@@ -153090,27 +153544,52 @@ index 99039e0..3680356 100644
              fd,filename = tempfile.mkstemp(suffix='.yumtx', prefix=prefix)
              f = os.fdopen(fd, 'w')
          else:
-@@ -5244,7 +5997,7 @@ class YumBase(depsolve.Depsolve):
+@@ -5244,13 +6024,17 @@ class YumBase(depsolve.Depsolve):
          
          msg = "%s\n" % self.rpmdb.simpleVersion(main_only=True)[0]
          msg += "%s\n" % self.ts.getTsFlags()
 -        if self.tsInfo.pkgSack is None: # rm Transactions don't have pkgSack
+-            msg += "0\n"
++
 +        if self.tsInfo._pkgSack is None: # Transactions have pkgSack?
-             msg += "0\n"
++            msg += "1\n"
          else:
-             msg += "%s\n" % len(self.repos.listEnabled())
-@@ -5266,7 +6019,17 @@ class YumBase(depsolve.Depsolve):
+-            msg += "%s\n" % len(self.repos.listEnabled())
++            msg += "%s\n" % (len(self.repos.listEnabled()) + 1)
+             for r in self.repos.listEnabled():
+                 msg += "%s:%s:%s\n" % (r.id, len(r.sack), r.repoXML.revision)
  
-         
-     def load_ts(self, filename, ignorerpm=None, ignoremissing=None):
++        # Save what we think the future rpmdbv will be.
++        msg += "%s:%s\n" % ('installed', self.tsInfo.futureRpmDBVersion())
++
+         msg += "%s\n" % len(self.tsInfo.getMembers())
+         for txmbr in self.tsInfo.getMembers():
+             msg += txmbr._dump()
+@@ -5260,13 +6044,25 @@ class YumBase(depsolve.Depsolve):
+         except (IOError, OSError), e:
+             self._ts_save_file = None
+             if auto:
+-                self.logger.critical(_("Could not save transaction file %s: %s") % (filename, str(e)))
++                self.logger.critical(_("Could not save transaction file %s: %s") % (filename, exception2msg(e)))
+             else:
+-                raise Errors.YumBaseError(_("Could not save transaction file %s: %s") % (filename, str(e)))
+-
+-        
+-    def load_ts(self, filename, ignorerpm=None, ignoremissing=None):
 -        """loads a transaction from a .yumtx file"""
++                raise Errors.YumBaseError(_("Could not save transaction file %s: %s") % (filename, exception2msg(e)))
++
++        
++    def load_ts(self, filename, ignorerpm=None, ignoremissing=None,
++                ignorenewrpm=None):
 +        """Load a transaction from a .yumtx file.
 +
 +        :param filename: the name of the file to load the transaction
 +           from
-+        :param ignorerpm: whether to ignore messages from rpm
++        :param ignorerpm: whether to ignore starting rpmdb version mismatch.
 +        :param ignoremissing: whether to ignore that there may be
 +           transaction members missing
++        :param ignorenewrpm: whether to ignore ending rpmdb version mismatch.
 +        :return: the members of the loaded transaction
 +        :raises: :class:`yum.Errors.YumBaseError` if there are problems
 +           loading the transaction
@@ -153118,7 +153597,33 @@ index 99039e0..3680356 100644
          # check rpmversion - if not match throw a fit
          # check repoversions  (and repos)- if not match throw a fit
          # load each txmbr - if pkgs being updated don't exist, bail w/error
-@@ -5292,6 +6055,16 @@ class YumBase(depsolve.Depsolve):
+@@ -5276,26 +6072,45 @@ class YumBase(depsolve.Depsolve):
+         try:
+             data = open(filename, 'r').readlines()
+         except (IOError, OSError), e:
+-            raise Errors.YumBaseError(_("Could not access/read saved transaction %s : %s") % (filename, str(e)))
++            raise Errors.YumBaseError(_("Could not access/read saved transaction %s : %s") % (filename, exception2msg(e)))
+             
+ 
+         if ignorerpm is None:
+             ignorerpm = self.conf.loadts_ignorerpm
++        if ignorenewrpm is None:
++            ignorenewrpm = self.conf.loadts_ignorenewrpm
+         if ignoremissing is None:
+             ignoremissing = self.conf.loadts_ignoremissing
++
++        #  Inherit this, because for the ending version to match the starting
++        # version must match.
++        if ignorerpm:
++            ignorenewrpm = True
+             
+         # data format
+         # 0 == rpmdb version
+         # 1 == tsflags
+         # 2 == numrepos
+         # 3:numrepos = repos
++        #  -- post 3.2.29 update: 'installed' repo. added with the values as the
++        #                         new rpmdb version.
          # 3+numrepos = num pkgs
          # 3+numrepos+1 -> EOF= txmembers
          
@@ -153135,7 +153640,31 @@ index 99039e0..3680356 100644
          # rpm db ver
          rpmv = data[0].strip()
          if rpmv != str(self.rpmdb.simpleVersion(main_only=True)[0]):
-@@ -5329,6 +6102,7 @@ class YumBase(depsolve.Depsolve):
+-            msg = _("rpmdb ver mismatched saved transaction version, ")
++            msg = _("rpmdb ver mismatched saved transaction version,")
+             if ignorerpm:
+                 msg += _(" ignoring, as requested.")
+                 self.logger.critical(_(msg))
+@@ -5318,8 +6133,17 @@ class YumBase(depsolve.Depsolve):
+         numrepos = int(data[2].strip())
+         repos = []
+         rindex=3+numrepos
++        future_rpmdbv = None
+         for r in data[3:rindex]:
+-            repos.append(r.strip().split(':'))
++            repo = r.strip().split(':')
++
++            if repo and repo[0] == 'installed':
++                #  This is an update hack to list the _future_ rpmdb version.
++                # Doing it this way allows older yum's to load newer ts files.
++                future_rpmdbv = "%s:%s" % (repo[1], repo[2])
++                continue
++
++            repos.append(repo)
+ 
+         # pkgs/txmbrs
+         numpkgs = int(data[rindex].strip())
+@@ -5329,6 +6153,7 @@ class YumBase(depsolve.Depsolve):
          pkgcount = 0
          pkgprob = False
          curpkg = None
@@ -153143,6 +153672,67 @@ index 99039e0..3680356 100644
          for l in data[pkgstart:]:
              l = l.rstrip()
              # our main txmbrs
+@@ -5438,6 +6263,11 @@ class YumBase(depsolve.Depsolve):
+                 msg += _(" aborting.")
+                 raise Errors.YumBaseError(msg)
+             
++        if len(self.tsInfo) != pkgcount:
++            future_rpmdbv = None
++        if future_rpmdbv is not None:
++            self.tsInfo._check_future_rpmdbv = (pkgcount, future_rpmdbv,
++                                                ignorenewrpm)
+         return self.tsInfo.getMembers()
+ 
+     def _remove_old_deps(self):
+@@ -5470,18 +6300,6 @@ class YumBase(depsolve.Depsolve):
+                     if requiring == required: # if they are self-requiring skip them
+                         continue
+                         
+-                # 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
+-                            
+                     #for tbi_pkg in self.tsInfo.getMembersWithState(output_states=TS_INSTALL_STATES):
+                     #   for reqtuple in tbi_pkg.po.requires:
+                     #        if required.provides_for(reqtuple):
+@@ -5533,7 +6351,24 @@ class YumBase(depsolve.Depsolve):
+                     # Debugging output
+                     self.verbose_logger.log(logginglevels.DEBUG_2, _("%s has revdep %s which was user-installed."), pkg, curpkg)
+                     ok_to_remove[pkg] = False
++                    ok_to_remove[curpkg] = False
+                     return True
++
++                #  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 curpkg.provides:
++                    if self.tsInfo.getNewRequires(provn, provf, provevr).keys():
++                        ok_to_remove[pkg] = False
++                        ok_to_remove[curpkg] = False
++                        self.verbose_logger.log(logginglevels.DEBUG_2, _("%s is needed by a package to be installed."), curpkg)
++                        return True
++                for fn in curpkg.filelist + curpkg.dirlist:
++                    if self.tsInfo.getNewRequires(fn, None,(None,None,None)).keys():
++                        ok_to_remove[pkg] = False
++                        ok_to_remove[curpkg] = False
++                        self.verbose_logger.log(logginglevels.DEBUG_2, _("%s is needed by a package to be installed."), curpkg)
++                        return True
++
+                 visited[curpkg] = True
+             all_leaves_visited = True
+             leaves = curpkg.requiring_packages()
+@@ -5547,4 +6382,3 @@ class YumBase(depsolve.Depsolve):
+         # Debugging output
+         self.verbose_logger.log(logginglevels.DEBUG_2, _("%s has no user-installed revdeps."), pkg)
+         return False
+-
 diff --git a/yum/callbacks.py b/yum/callbacks.py
 index 7ad25ce..a9a8e53 100644
 --- a/yum/callbacks.py
@@ -153291,7 +153881,7 @@ index 7ad25ce..a9a8e53 100644
          pass
          
 diff --git a/yum/config.py b/yum/config.py
-index d09511f..fe7e1cb 100644
+index d09511f..2bf4f45 100644
 --- a/yum/config.py
 +++ b/yum/config.py
 @@ -45,15 +45,18 @@ from misc import get_uuid, read_in_items_from_dot_dir
@@ -153991,8 +154581,9 @@ index d09511f..fe7e1cb 100644
      commands = ListOption()
      exclude = ListOption()
 -    failovermethod = Option('roundrobin')
+-    proxy = UrlOption(schemes=('http', 'ftp', 'https'), allow_none=True)
 +    failovermethod = Option(__main_failovermethod_default__)
-     proxy = UrlOption(schemes=('http', 'ftp', 'https'), allow_none=True)
++    proxy = UrlOption(default=False, schemes=('http', 'ftp', 'https'), allow_none=True)
      proxy_username = Option()
      proxy_password = Option()
      username = Option()
@@ -154020,7 +154611,7 @@ index d09511f..fe7e1cb 100644
      alwaysprompt = BoolOption(True)
      exactarch = BoolOption(True)
      tolerant = BoolOption(True)
-@@ -681,11 +778,16 @@ class YumConf(StartupConf):
+@@ -681,11 +778,17 @@ class YumConf(StartupConf):
      enable_group_conditionals = BoolOption(True)
      groupremove_leaf_only = BoolOption(False)
      group_package_types = ListOption(['mandatory', 'default'])
@@ -154034,10 +154625,11 @@ index d09511f..fe7e1cb 100644
 +    ip_resolve = CaselessSelectionOption(
 +            allowed = ('ipv4', 'ipv6', 'whatever'),
 +            mapper  = {'4': 'ipv4', '6': 'ipv6'})
++    max_connections = IntOption(0)
  
      http_caching = SelectionOption('all', ('none', 'packages', 'all'))
      metadata_expire = SecondsOption(60 * 60 * 6) # Time in seconds (6h).
-@@ -698,12 +800,14 @@ class YumConf(StartupConf):
+@@ -698,12 +801,14 @@ class YumConf(StartupConf):
      #  Note that "instant" is the old behaviour, but group:primary is very
      # similar but better :).
      mdpolicy = ListOption(['group:primary'])
@@ -154054,7 +154646,7 @@ index d09511f..fe7e1cb 100644
  
      color = SelectionOption('auto', ('auto', 'never', 'always'),
                              mapper={'on' : 'always', 'yes' : 'always',
-@@ -715,11 +819,13 @@ class YumConf(StartupConf):
+@@ -715,11 +820,13 @@ class YumConf(StartupConf):
      color_list_installed_newer = Option('bold,yellow')
      color_list_installed_reinstall = Option('normal')
      color_list_installed_extra = Option('bold,red')
@@ -154068,7 +154660,7 @@ index d09511f..fe7e1cb 100644
  
      color_update_installed = Option('normal')
      color_update_local     = Option('bold')
-@@ -731,6 +837,7 @@ class YumConf(StartupConf):
+@@ -731,6 +838,7 @@ class YumConf(StartupConf):
      sslverify = BoolOption(True)
      sslclientcert = Option()
      sslclientkey = Option()
@@ -154076,7 +154668,11 @@ index d09511f..fe7e1cb 100644
  
      history_record = BoolOption(True)
      history_record_packages = ListOption(['yum', 'rpm'])
-@@ -747,15 +854,25 @@ class YumConf(StartupConf):
+@@ -744,18 +852,29 @@ class YumConf(StartupConf):
+     
+     loadts_ignoremissing = BoolOption(False)
+     loadts_ignorerpm = BoolOption(False)
++    loadts_ignorenewrpm = BoolOption(False)
      
      clean_requirements_on_remove = BoolOption(False)
  
@@ -154102,7 +154698,7 @@ index d09511f..fe7e1cb 100644
          output = '[main]\n'
          # we exclude all vars which start with _ or are in this list:
          excluded_vars = ('cfg', 'uid', 'yumvar', 'progress_obj', 'failure_obj',
-@@ -778,14 +895,12 @@ class YumConf(StartupConf):
+@@ -778,14 +897,12 @@ class YumConf(StartupConf):
          return output
  
  class RepoConf(BaseConfig):
@@ -154120,7 +154716,7 @@ index d09511f..fe7e1cb 100644
          ck = self.__cached_keys
          if not isinstance(self, RepoConf):
              ck = set()
-@@ -823,39 +938,43 @@ class RepoConf(BaseConfig):
+@@ -823,39 +940,44 @@ class RepoConf(BaseConfig):
      bandwidth = Inherit(YumConf.bandwidth)
      throttle = Inherit(YumConf.throttle)
      timeout = Inherit(YumConf.timeout)
@@ -154142,6 +154738,7 @@ index d09511f..fe7e1cb 100644
 +    ssl_check_cert_permissions = Inherit(YumConf.ssl_check_cert_permissions)
  
      skip_if_unavailable = BoolOption(False)
++    async = BoolOption(True)
      
  class VersionGroupConf(BaseConfig):
 +    """Option definitions for version groups."""
@@ -154175,7 +154772,7 @@ index d09511f..fe7e1cb 100644
  
      # ' xemacs syntax hack
  
-@@ -876,20 +995,24 @@ def readStartupConfig(configfile, root):
+@@ -876,20 +998,24 @@ def readStartupConfig(configfile, root):
              raise Errors.ConfigError("All plugin search paths must be absolute")
      # Stuff this here to avoid later re-parsing
      startupconf._parser = parser
@@ -154206,7 +154803,7 @@ index d09511f..fe7e1cb 100644
      
      # ' xemacs syntax hack
  
-@@ -956,6 +1079,12 @@ def readMainConfig(startupconf):
+@@ -956,6 +1082,12 @@ def readMainConfig(startupconf):
      return yumconf
  
  def readVersionGroupsConfig(configfile="/etc/yum/version-groups.conf"):
@@ -154219,7 +154816,7 @@ index d09511f..fe7e1cb 100644
      parser = ConfigParser()
      confpp_obj = ConfigPreProcessor(configfile)
      try:
-@@ -970,17 +1099,16 @@ def readVersionGroupsConfig(configfile="/etc/yum/version-groups.conf"):
+@@ -970,17 +1102,16 @@ def readVersionGroupsConfig(configfile="/etc/yum/version-groups.conf"):
  
  
  def getOption(conf, section, name, option):
@@ -154247,7 +154844,7 @@ index d09511f..fe7e1cb 100644
      try: 
          val = conf.get(section, name)
      except (NoSectionError, NoOptionError):
-@@ -1028,7 +1156,10 @@ def _getsysver(installroot, distroverpkg):
+@@ -1028,7 +1159,10 @@ def _getsysver(installroot, distroverpkg):
      if idx.count() == 0:
          releasever = '$releasever'
      else:
@@ -154259,7 +154856,7 @@ index d09511f..fe7e1cb 100644
          releasever = hdr['version']
          del hdr
      del idx
-@@ -1036,13 +1167,12 @@ def _getsysver(installroot, distroverpkg):
+@@ -1036,13 +1170,12 @@ def _getsysver(installroot, distroverpkg):
      return releasever
  
  def writeRawRepoFile(repo,only=None):
@@ -154278,7 +154875,7 @@ index d09511f..fe7e1cb 100644
      if not _use_iniparse:
          return
  
-@@ -1069,7 +1199,7 @@ def writeRawRepoFile(repo,only=None):
+@@ -1069,7 +1202,7 @@ def writeRawRepoFile(repo,only=None):
          #  If the value is the same, but just interpreted ... when we don't want
          # to keep the interpreted values.
          if (name in ini[section_id] and
@@ -155525,8 +156122,41 @@ index 0000000..625ee66
 +                    break
 +
 +        return returns.values()
+diff --git a/yum/metalink.py b/yum/metalink.py
+index aaa4f25..51895fd 100755
+--- a/yum/metalink.py
++++ b/yum/metalink.py
+@@ -180,6 +180,7 @@ class MetaLinkRepoMD:
+         self.repomd = None
+         self.old_repomds = []
+         self.mirrors = []
++        self._host2mc = {}
+         if not os.path.exists(filename):
+             raise MetaLinkRepoErrorParseFail, "File %s does not exist" %filename
+         try:
+@@ -225,8 +226,6 @@ class MetaLinkRepoMD:
+         # Get the hostname from a url, stripping away any usernames/passwords
+         # Borrowd from fastestmirror
+         url2host = lambda url: url.split('/')[2].split('@')[-1]
+-        hosts = set() # Don't want multiple urls for one host in plain mode
+-                      # The list of URLs is sorted, so http is before ftp
+ 
+         for mirror in self.mirrors:
+             url = mirror.url
+@@ -237,9 +236,9 @@ class MetaLinkRepoMD:
+             elif (url.startswith("http:") or url.startswith("ftp:") or
+                   url.startswith("https:")):
+                 host = url2host(url)
+-                if host in hosts:
++                if host in self._host2mc:
+                     continue
+-                hosts.add(host)
++                self._host2mc[host] = mirror.max_connections
+             else:
+                 continue
+ 
 diff --git a/yum/misc.py b/yum/misc.py
-index 2f6ddfe..5321003 100644
+index 2f6ddfe..59aff5d 100644
 --- a/yum/misc.py
 +++ b/yum/misc.py
 @@ -8,6 +8,7 @@ import os
@@ -155555,7 +156185,16 @@ index 2f6ddfe..5321003 100644
  def getgpgkeyinfo(rawkey, multiple=False):
      '''Return a dict of info for the given ASCII armoured key text
  
-@@ -940,14 +952,16 @@ def unlink_f(filename):
+@@ -746,6 +758,8 @@ def _decompress_chunked(source, dest, ztype):
+             data = s_fn.read(1024000)
+         except IOError:
+             break
++        except EOFError:
++            break
+         
+         if not data: break
+ 
+@@ -940,14 +954,16 @@ def unlink_f(filename):
          if e.errno != errno.ENOENT:
              raise
  
@@ -155576,17 +156215,59 @@ index 2f6ddfe..5321003 100644
  
  def _getloginuid():
      """ Get the audit-uid/login-uid, if available. None is returned if there
-@@ -1112,10 +1126,12 @@ def decompress(filename, dest=None, fn_only=False, check_timestamps=False):
-         if check_timestamps:
-             fi = stat_f(filename)
-             fo = stat_f(out)
+@@ -992,9 +1008,17 @@ def setup_locale(override_codecs=True, override_time=False):
+         locale.setlocale(locale.LC_ALL, 'C')
+         
+     if override_codecs:
+-        import codecs
+-        sys.stdout = codecs.getwriter(locale.getpreferredencoding())(sys.stdout)
+-        sys.stdout.errors = 'replace'
++        class UnicodeStream:
++            def __init__(self, stream, encoding):
++                self.stream = stream
++                self.encoding = encoding
++            def write(self, s):
++                if isinstance(s, unicode):
++                    s = s.encode(self.encoding, 'replace')
++                self.stream.write(s)
++            def __getattr__(self, name):
++                return getattr(self.stream, name)
++        sys.stdout = UnicodeStream(sys.stdout, locale.getpreferredencoding())
+ 
+ 
+ def get_my_lang_code():
+@@ -1105,17 +1129,26 @@ def decompress(filename, dest=None, fn_only=False, check_timestamps=False):
+             out = filename.replace('.xz', '')
+         
+     else:
+-        out = filename # returning the same file since it is not compressed
+-        ztype = None
++        return filename # returning the same file since it is not compressed
+     
+-    if ztype and not fn_only:
+-        if check_timestamps:
+-            fi = stat_f(filename)
+-            fo = stat_f(out)
 -            if fi and fo and fo.st_mtime > fi.st_mtime:
-+            if fi and fo and fo.st_mtime == fi.st_mtime:
++    if check_timestamps:
++        fi = stat_f(filename)
++        fo = stat_f(out)
++        if fi and fo:
++            if fo.st_mtime == fi.st_mtime:
                  return out
++            if fn_only:
++                # out exists but not valid
++                return None
  
-         _decompress_chunked(filename, out, ztype)
-+        if check_timestamps and fi:
-+            os.utime(out, (fi.st_mtime, fi.st_mtime))
+-        _decompress_chunked(filename, out, ztype)
++    if not fn_only:
++        try:
++            _decompress_chunked(filename, out, ztype)
++            if check_timestamps and fi:
++                os.utime(out, (fi.st_mtime, fi.st_mtime))
++        except:
++            unlink_f(out)
++            raise
          
      return out
      
@@ -155886,6 +156567,23 @@ index 5ef9951..da31971 100644
  
      def _is_pre_req(self, flag):
          """check the flags for a requirement, return 1 or 0 whether or not requires
+diff --git a/yum/parser.py b/yum/parser.py
+index fccf528..f443ce7 100644
+--- a/yum/parser.py
++++ b/yum/parser.py
+@@ -73,7 +73,11 @@ class ConfigPreProcessor:
+         if scheme == '':
+             # check it to make sure it's not a relative file url
+             if configfile[0] != '/':
+-                configfile = os.getcwd() + '/' + configfile
++                try:
++                    rootdir = os.getcwd() + "/"
++                except:
++                    rootdir = "/"
++                configfile = rootdir + configfile
+             url = 'file://' + configfile
+         else:
+             url = configfile
 diff --git a/yum/pgpmsg.py b/yum/pgpmsg.py
 index ee825c6..dae60c9 100644
 --- a/yum/pgpmsg.py
@@ -156454,6 +157152,92 @@ index bfc49b7..9ddcae6 100644
      a = parsever(a)
      b = parsever(b)
  
+diff --git a/yum/repos.py b/yum/repos.py
+index 3793bad..4b1d52e 100644
+--- a/yum/repos.py
++++ b/yum/repos.py
+@@ -22,6 +22,7 @@ import misc
+ 
+ import Errors
+ from packageSack import MetaSack
++import urlgrabber.grabber
+ 
+ from weakref import proxy as weakref
+ 
+@@ -67,6 +68,38 @@ class RepoStorage:
+         self._cache_enabled_repos = []
+         self.quick_enable_disable = {}
+ 
++    def retrieveAllMD(self):
++        """ Download metadata for all enabled repositories,
++            based on mdpolicy.
++        """
++
++        if not hasattr(urlgrabber.grabber, 'parallel_wait'):
++            return
++
++        repos = []
++        for repo in self.listEnabled():
++            if repo._async and repo._commonLoadRepoXML(repo):
++                mdtypes = repo._mdpolicy2mdtypes()
++                downloading = repo._commonRetrieveDataMD_list(mdtypes)
++                repos.append((repo, downloading, [False]))
++
++        # with sizes first, then without sizes..
++	for no_size in (False, True):
++            for repo, downloading, error in repos:
++                def failfunc(obj, error=error):
++                    error[0] = True
++                for (ndata, nmdtype) in downloading:
++                    if (ndata.size is None) == no_size:
++                        repo._retrieveMD(nmdtype, async=True, failfunc=failfunc)
++            urlgrabber.grabber.parallel_wait()
++
++        # done or revert
++        for repo, downloading, error in repos:
++            if error[0]: # some MD failed?
++                repo._revertOldRepoXML()
++            else:
++                repo._commonRetrieveDataMD_done(downloading)
++
+     def doSetup(self, thisrepo = None):
+         
+         self.ayum.plugins.run('prereposetup')
+@@ -89,6 +122,7 @@ class RepoStorage:
+                 self.disableRepo(repo.id)
+                 
+         self._setup = True
++        self.retrieveAllMD()
+         self.ayum.plugins.run('postreposetup')
+         
+     def __str__(self):
+@@ -223,8 +257,9 @@ class RepoStorage:
+         
+         self._cachedir = cachedir
+         for repo in self.repos.values():
+-            repo.old_base_cache_dir = repo.basecachedir
+-            repo.basecachedir = cachedir
++            if cachedir != repo.basecachedir:
++                repo.old_base_cache_dir = repo.basecachedir
++                repo.basecachedir = cachedir
+ 
+ 
+     def setProgressBar(self, obj):
+@@ -288,6 +323,14 @@ class RepoStorage:
+         else:
+             data = [ mdtype ]
+          
++        if hasattr(urlgrabber.grabber, 'parallel_wait'):
++            # download all metadata in parallel
++            for repo in myrepos:
++                if repo._async:
++                    sack = repo.getPackageSack()
++                    sack._retrieve_async(repo, data)
++            urlgrabber.grabber.parallel_wait()
++
+         for repo in myrepos:
+             sack = repo.getPackageSack()
+             try:
 diff --git a/yum/rpmsack.py b/yum/rpmsack.py
 index e289a7a..ed8e3d1 100644
 --- a/yum/rpmsack.py
@@ -156627,10 +157411,21 @@ index 9b265f9..24a1f9e 100644
 +
 +        self.display.verify_txmbr(self.base, txmbr, count)
 diff --git a/yum/sqlitesack.py b/yum/sqlitesack.py
-index 8a6f6f3..f6df93e 100644
+index 8a6f6f3..ba929de 100644
 --- a/yum/sqlitesack.py
 +++ b/yum/sqlitesack.py
-@@ -406,7 +406,7 @@ class YumAvailablePackageSqlite(YumAvailablePackage, PackageObject, RpmBase):
+@@ -382,6 +382,10 @@ class YumAvailablePackageSqlite(YumAvailablePackage, PackageObject, RpmBase):
+ 
+     def returnPrco(self, prcotype, printable=False):
+         prcotype = _share_data(prcotype)
++        if prcotype == 'strong_requires':
++            # pkg not installed so we don't know require flags yet
++            # returning all requires should work in most cases
++            prcotype = 'requires'
+         if isinstance(self.prco[prcotype], tuple):
+             sql = "SELECT name, version, release, epoch, flags " \
+                   "FROM %s WHERE pkgKey = ?" % prcotype
+@@ -406,7 +410,7 @@ class YumAvailablePackageSqlite(YumAvailablePackage, PackageObject, RpmBase):
          requires = []
          for ob in cur:
              pre = "0"
@@ -156639,7 +157434,7 @@ index 8a6f6f3..f6df93e 100644
                  pre = "1"
              prco_set = (_share_data(ob['name']), _share_data(ob['flags']),
                          (_share_data(ob['epoch']),
-@@ -917,8 +917,7 @@ class YumSqlitePackageSack(yumRepo.YumPackageSack):
+@@ -917,8 +921,7 @@ class YumSqlitePackageSack(yumRepo.YumPackageSack):
  
          # ultra simple optimization 
          if misc.re_primary_filename(name):
@@ -156650,7 +157445,7 @@ index 8a6f6f3..f6df93e 100644
          if len(self.filelistsdb) == 0:
              # grab repo object from primarydb and force filelists population in this sack using repo
 diff --git a/yum/transactioninfo.py b/yum/transactioninfo.py
-index 4d89d83..97de8f0 100644
+index 4d89d83..b584338 100644
 --- a/yum/transactioninfo.py
 +++ b/yum/transactioninfo.py
 @@ -87,7 +87,8 @@ class TransactionData:
@@ -156663,7 +157458,17 @@ index 4d89d83..97de8f0 100644
          self.pkgSackPackages = 0
          self.localSack = PackageSack()
          self._inSack = GetProvReqOnlyPackageSack()
-@@ -115,6 +116,18 @@ class TransactionData:
+@@ -105,6 +106,9 @@ class TransactionData:
+         self.reinstalled = []
+         self.downgraded = []
+         self.failed = []
++
++        self._future_rpmdbv = None
++        self._check_future_rpmdbv = None
+         
+     def __len__(self):
+         return len(self.pkgdict)
+@@ -115,6 +119,18 @@ class TransactionData:
          else:
              return iter(self.getMembers())
  
@@ -156682,7 +157487,7 @@ index 4d89d83..97de8f0 100644
      def debugprint(self, msg):
          if self.debug:
              print msg
-@@ -208,7 +221,9 @@ class TransactionData:
+@@ -208,7 +224,9 @@ class TransactionData:
                  txmbrs = self.matchNaevr(na[0], na[1])
  
          if not txmbrs:
@@ -156693,7 +157498,7 @@ index 4d89d83..97de8f0 100644
                  pkgs = []
              else:
                  pkgs = self.pkgSack.returnPackages(patterns=[pattern])
-@@ -547,9 +562,10 @@ class TransactionData:
+@@ -547,9 +565,10 @@ class TransactionData:
          return txmbr
  
  
@@ -156706,6 +157511,27 @@ index 4d89d83..97de8f0 100644
  
      def getNewProvides(self, name, flag=None, version=(None, None, None)):
          """return dict { packages -> list of matching provides }
+@@ -619,6 +638,12 @@ class TransactionData:
+         """ Return a simple version for the future rpmdb. Works like
+             rpmdb.simpleVersion(main_only=True)[0], but for the state the rpmdb
+             will be in after the transaction. """
++
++        if self._future_rpmdbv is not None:
++            sc, ret = self._future_rpmdbv
++            if sc == self.state_counter:
++                return ret
++
+         pkgs = self.rpmdb.returnPackages()
+         _reinstalled_pkgtups = {}
+         for txmbr in self.getMembersWithState(None, TS_INSTALL_STATES):
+@@ -658,6 +683,7 @@ class TransactionData:
+ 
+         self.rpmdb.transactionCachePackageChecksums(pkg_checksum_tups)
+ 
++        self._future_rpmdbv = (self.state_counter, main)
+         return main
+     
+     def findObsoletedByThisMember(self, txmbr):
 diff --git a/yum/update_md.py b/yum/update_md.py
 index 2cb1acb..7da6a08 100644
 --- a/yum/update_md.py
@@ -156726,7 +157552,7 @@ index 2cb1acb..7da6a08 100644
          self._md[item] = val
  
 diff --git a/yum/yumRepo.py b/yum/yumRepo.py
-index e5e9ece..62e53f8 100644
+index e5e9ece..57a1a29 100644
 --- a/yum/yumRepo.py
 +++ b/yum/yumRepo.py
 @@ -20,10 +20,12 @@ import time
@@ -156750,8 +157576,131 @@ index e5e9ece..62e53f8 100644
  from constants import *
  import metalink
  
-@@ -434,22 +437,13 @@ class YumRepository(Repository, config.RepoConf):
-         if self.proxy not in empty:
+@@ -121,6 +124,25 @@ class YumPackageSack(packageSack.PackageSack):
+             # umm, wtf?
+             pass
+ 
++    def _retrieve_async(self, repo, data):
++        """ Just schedule the metadata downloads """
++
++        for item in data:
++            if item in self.added.get(repo, []):
++                continue
++            if item == 'metadata':
++                mydbtype = 'primary_db'
++            elif item == 'filelists':
++                mydbtype = 'filelists_db'
++            elif item == 'otherdata':
++                mydbtype = 'other_db'
++            else:
++                continue
++
++            if self._check_db_version(repo, mydbtype):
++                if not self._check_uncompressed_db(repo, mydbtype):
++                    repo._retrieveMD(mydbtype, async=True, failfunc=None)
++
+     def populate(self, repo, mdtype='metadata', callback=None, cacheonly=0):
+         if mdtype == 'all':
+             data = ['metadata', 'filelists', 'otherdata']
+@@ -162,6 +184,25 @@ class YumPackageSack(packageSack.PackageSack):
+                 continue
+ 
+             if self._check_db_version(repo, mydbtype):
++                #  Use gen decompression on DB files. Keeps exactly what we
++                # downloaded in the download dir.
++
++                # Backwards compat. ... try the old uncompressed version first.
++                db_un_fn = self._check_uncompressed_db(repo, mydbtype)
++                if not db_un_fn:
++                    db_un_fn = self._check_uncompressed_db_gen(repo, mydbtype)
++
++                if not db_un_fn:
++                    db_fn = repo._retrieveMD(mydbtype)
++                    if db_fn:
++                        db_un_fn = self._check_uncompressed_db_gen(repo,
++                                                                   mydbtype)
++                    if not db_un_fn: # Shouldn't happen?
++                        raise URLGrabError(-1, 'Check uncompressed DB failed')
++
++                dobj = repo.cacheHandler.open_database(db_un_fn)
++
++            elif self._check_db_version(repo, mydbtype):
+                 # see if we have the uncompressed db and check it's checksum vs the openchecksum
+                 # if not download the compressed file
+                 # decompress it
+@@ -180,7 +221,17 @@ class YumPackageSack(packageSack.PackageSack):
+ 
+             else:
+                 repo._xml2sqlite_local = True
++                # Download...
+                 xml = repo_get_function()
++
++                #  Use generated dir. and handle compression types metadata
++                # parser doesn't understand.
++                gen = mymdtype + '.xml'
++                ret = misc.repo_gen_decompress(xml, gen, cached=repo.cache)
++                if not ret:
++                    raise URLGrabError(-1, 'Decompress DB failed')
++                xml = ret
++                # Convert XML => .sqlite
+                 xmldata = repo.repoXML.getData(mymdtype)
+                 (ctype, csum) = xmldata.checksum
+                 dobj = repo_cache_function(xml, csum)
+@@ -193,6 +244,25 @@ class YumPackageSack(packageSack.PackageSack):
+         # get rid of all this stuff we don't need now
+         del repo.cacheHandler
+ 
++    def _check_uncompressed_db_gen(self, repo, mdtype, fast=True):
++        """return file name of db in gen/ dir if good, None if not"""
++
++        mydbdata         = repo.repoXML.getData(mdtype)
++        (r_base, remote) = mydbdata.location
++        fname            = os.path.basename(remote)
++        compressed_fn    = repo.cachedir + '/' + fname
++        db_un_fn         = mdtype + '.sqlite'
++
++        if not repo._checkMD(compressed_fn, mdtype, data=mydbdata,
++                             check_can_fail=fast, fast=fast):
++            return None
++
++        ret = misc.repo_gen_decompress(compressed_fn, db_un_fn,
++                                       cached=repo.cache)
++        if ret:
++            return self._check_uncompressed_db_fn(repo, mdtype, ret)
++        return None
++
+     def _check_uncompressed_db(self, repo, mdtype):
+         """return file name of uncompressed db is good, None if not"""
+         mydbdata = repo.repoXML.getData(mdtype)
+@@ -201,9 +271,11 @@ class YumPackageSack(packageSack.PackageSack):
+         compressed_fn = repo.cachedir + '/' + fname
+         db_un_fn = misc.decompress(compressed_fn, fn_only=True)
+ 
++        return self._check_uncompressed_db_fn(repo, mdtype, db_un_fn)
++
++    def _check_uncompressed_db_fn(self, repo, mdtype, db_un_fn):
+         result = None
+ 
+-        repo._preload_md_from_system_cache(os.path.basename(db_un_fn))
+         if os.path.exists(db_un_fn):
+             if skip_old_DBMD_check and repo._using_old_MD:
+                 return db_un_fn
+@@ -285,6 +357,7 @@ class YumRepository(Repository, config.RepoConf):
+ 
+         self._grabfunc = None
+         self._grab = None
++        self._async = False
+ 
+     def __cmp__(self, other):
+         """ Sort yum repos. by cost, and then by alphanumeric on their id. """
+@@ -431,25 +504,18 @@ class YumRepository(Repository, config.RepoConf):
+         self._proxy_dict = {} # zap it
+         proxy_string = None
+         empty = (None, '_none_', '')
+-        if self.proxy not in empty:
++        if self.proxy is None:  # got 'proxy=_none_'
++            proxy_string = ''   # this disables default proxies
++        elif self.proxy:
              proxy_string = '%s' % self.proxy
              if self.proxy_username not in empty:
 -                proxy_parsed = urlparse.urlsplit(self.proxy, allow_fragments=0)
@@ -156778,7 +157727,29 @@ index e5e9ece..62e53f8 100644
  
          if proxy_string is not None:
              self._proxy_dict['http'] = proxy_string
-@@ -499,6 +493,7 @@ class YumRepository(Repository, config.RepoConf):
+@@ -488,8 +554,20 @@ class YumRepository(Repository, config.RepoConf):
+                                     copy_local=self.copy_local,
+                                     reget='simple',
+                                     **ugopts)
++        def add_mc(url):
++            host = urlparse.urlsplit(url).netloc
++            mc = self.metalink_data._host2mc.get(host)
++            if mc > 0:
++                url = {
++                    'mirror': misc.to_utf8(url),
++                    'kwargs': { 'max_connections': mc },
++                }
++            return url
++        urls = self.urls
++        if self.metalink:
++            urls = map(add_mc, urls)
+ 
+-        self._grab = mgclass(self._grabfunc, self.urls,
++        self._grab = mgclass(self._grabfunc, urls,
+                              failure_callback=self.mirror_failure_obj)
+ 
+     def _default_grabopts(self, cache=True):
+@@ -499,6 +577,7 @@ class YumRepository(Repository, config.RepoConf):
                   'throttle': self.throttle,
                   'proxies': self.proxy_dict,
                   'timeout': self.timeout,
@@ -156786,7 +157757,16 @@ index e5e9ece..62e53f8 100644
                   'http_headers': tuple(self.__headersListFromDict(cache=cache)),
                   'ssl_verify_peer': self.sslverify,
                   'ssl_verify_host': self.sslverify,
-@@ -796,6 +791,16 @@ class YumRepository(Repository, config.RepoConf):
+@@ -751,7 +830,7 @@ class YumRepository(Repository, config.RepoConf):
+ 
+     def _getFile(self, url=None, relative=None, local=None, start=None, end=None,
+             copy_local=None, checkfunc=None, text=None, reget='simple', 
+-            cache=True, size=None):
++            cache=True, size=None, **kwargs):
+         """retrieve file from the mirrorgroup for the repo
+            relative to local, optionally get range from
+            start to end, also optionally retrieve from a specific baseurl"""
+@@ -796,6 +875,16 @@ class YumRepository(Repository, config.RepoConf):
              except Errors.MediaError, e:
                  verbose_logger.log(logginglevels.DEBUG_2, "Error getting package from media; falling back to url %s" %(e,))
  
@@ -156803,7 +157783,34 @@ index e5e9ece..62e53f8 100644
          if url and scheme != "media":
              ugopts = self._default_grabopts(cache=cache)
              ug = URLGrabber(progress_obj = self.callback,
-@@ -1020,7 +1025,7 @@ class YumRepository(Repository, config.RepoConf):
+@@ -835,7 +924,8 @@ class YumRepository(Repository, config.RepoConf):
+                                            reget = reget,
+                                            checkfunc=checkfunc,
+                                            http_headers=headers,
+-                                           size=size
++                                           size=size,
++                                           **kwargs
+                                            )
+             except URLGrabError, e:
+                 errstr = "failure: %s from %s: %s" % (relative, self.id, e)
+@@ -847,7 +937,7 @@ class YumRepository(Repository, config.RepoConf):
+         return result
+     __get = _getFile
+ 
+-    def getPackage(self, package, checkfunc=None, text=None, cache=True):
++    def getPackage(self, package, checkfunc=None, text=None, cache=True, **kwargs):
+         remote = package.relativepath
+         local = package.localPkg()
+         basepath = package.basepath
+@@ -864,6 +954,7 @@ class YumRepository(Repository, config.RepoConf):
+                         text=text,
+                         cache=cache,
+                         size=package.size,
++                        **kwargs
+                         )
+ 
+     def getHeader(self, package, checkfunc = None, reget = 'simple',
+@@ -1020,7 +1111,7 @@ class YumRepository(Repository, config.RepoConf):
              if grab_can_fail:
                  return None
              raise Errors.RepoError, 'Error downloading file %s: %s' % (local, e)
@@ -156812,7 +157819,7 @@ index e5e9ece..62e53f8 100644
              misc.unlink_f(tfname)
              if grab_can_fail:
                  return None
-@@ -1260,6 +1265,9 @@ class YumRepository(Repository, config.RepoConf):
+@@ -1260,6 +1351,9 @@ class YumRepository(Repository, config.RepoConf):
          return True
  
      def _check_db_version(self, mdtype, repoXML=None):
@@ -156822,7 +157829,116 @@ index e5e9ece..62e53f8 100644
          if repoXML is None:
              repoXML = self.repoXML
          if mdtype in repoXML.repoData:
-@@ -1451,12 +1459,7 @@ class YumRepository(Repository, config.RepoConf):
+@@ -1277,11 +1371,11 @@ class YumRepository(Repository, config.RepoConf):
+             return None
+ 
+         if not file_check:
+-            compressed = dbmdtype.endswith("_db")
+-            local = self._get_mdtype_fname(data, compressed)
++            compressed = False
++            local = self._get_mdtype_fname(data)
+         else:
+             compressed = False
+-            local = self._get_mdtype_fname(data, False)
++            local = self._get_mdtype_fname(data)
+             if not os.path.exists(local):
+                 local = misc.decompress(local, fn_only=True)
+                 compressed = True
+@@ -1302,6 +1396,17 @@ class YumRepository(Repository, config.RepoConf):
+             into the delete list, this means metadata can change filename
+             without us leaking it. """
+ 
++        downloading = self._commonRetrieveDataMD_list(mdtypes)
++        for (ndata, nmdtype) in downloading:
++            if not self._retrieveMD(nmdtype, retrieve_can_fail=True):
++                self._revertOldRepoXML()
++                return False
++        self._commonRetrieveDataMD_done(downloading)
++        return True
++
++    def _commonRetrieveDataMD_list(self, mdtypes):
++        """ Return a list of metadata to be retrieved """
++
+         def _mdtype_eq(omdtype, odata, nmdtype, ndata):
+             """ Check if two returns from _get_mdtype_data() are equal. """
+             if ndata is None:
+@@ -1333,8 +1438,7 @@ class YumRepository(Repository, config.RepoConf):
+ 
+         # Inited twice atm. ... sue me
+         self._oldRepoMDData['new_MD_files'] = []
+-        downloading_with_size = []
+-        downloading_no_size   = []
++        downloading = []
+         for mdtype in all_mdtypes:
+             (nmdtype, ndata) = self._get_mdtype_data(mdtype)
+ 
+@@ -1371,43 +1475,16 @@ class YumRepository(Repository, config.RepoConf):
+             # No old repomd data, but we might still have uncompressed MD
+             if self._groupCheckDataMDValid(ndata, nmdtype, mdtype):
+                 continue
++            downloading.append((ndata, nmdtype))
++        return downloading
+ 
+-            if ndata.size is None:
+-                downloading_no_size.append((ndata, nmdtype))
+-            else:
+-                downloading_with_size.append((ndata, nmdtype))
+-
+-        if len(downloading_with_size) == 1:
+-            downloading_no_size.extend(downloading_with_size)
+-            downloading_with_size = []
+-
+-        remote_size = 0
+-        local_size  = 0
+-        for (ndata, nmdtype) in downloading_with_size: # Get total size...
+-            remote_size += int(ndata.size)
+-
+-        for (ndata, nmdtype) in downloading_with_size:
+-            urlgrabber.progress.text_meter_total_size(remote_size, local_size)
+-            if not self._retrieveMD(nmdtype, retrieve_can_fail=True):
+-                self._revertOldRepoXML()
+-                return False
+-            local_size += int(ndata.size)
+-        urlgrabber.progress.text_meter_total_size(0)
+-        for (ndata, nmdtype) in downloading_no_size:
+-            if not self._retrieveMD(nmdtype, retrieve_can_fail=True):
+-                self._revertOldRepoXML()
+-                return False
++    def _commonRetrieveDataMD_done(self, downloading):
++        """ Uncompress the downloaded metadata """
+ 
+-        for (ndata, nmdtype) in downloading_with_size + downloading_no_size:
++        for (ndata, nmdtype) in downloading:
+             local = self._get_mdtype_fname(ndata, False)
+-            if nmdtype.endswith("_db"): # Uncompress any compressed files
+-                dl_local = local
+-                local = misc.decompress(dl_local)
+-                misc.unlink_f(dl_local)
+             self._oldRepoMDData['new_MD_files'].append(local)
+-
+         self._doneOldRepoXML()
+-        return True
+ 
+     def _groupLoadRepoXML(self, text=None, mdtypes=None):
+         """ Retrieve the new repomd.xml from the repository, then check it
+@@ -1421,7 +1498,7 @@ class YumRepository(Repository, config.RepoConf):
+             self._commonRetrieveDataMD(mdtypes)
+ 
+     def _mdpolicy2mdtypes(self):
+-        md_groups = {'instant'       : [],
++        md_groups = {'instant'       : ['__None__'],
+                      'group:primary' : ['primary'],
+                      'group:small'   : ["primary", "updateinfo"],
+                      'group:main'    : ["primary", "group", "filelists",
+@@ -1436,6 +1513,7 @@ class YumRepository(Repository, config.RepoConf):
+         if not mdtypes or 'group:all' in mdtypes:
+             mdtypes = None
+         else:
++            mdtypes.discard("__None__")
+             mdtypes = sorted(list(mdtypes))
+         return mdtypes
+ 
+@@ -1451,12 +1529,7 @@ class YumRepository(Repository, config.RepoConf):
      def _getRepoXML(self):
          if self._repoXML:
              return self._repoXML
@@ -156836,19 +157952,95 @@ index e5e9ece..62e53f8 100644
          return self._repoXML
  
  
-@@ -1614,7 +1617,7 @@ class YumRepository(Repository, config.RepoConf):
+@@ -1514,7 +1587,7 @@ class YumRepository(Repository, config.RepoConf):
+         return self._checkMD(fn, mdtype, openchecksum)
+ 
+     def _checkMD(self, fn, mdtype, openchecksum=False,
+-                 data=None, check_can_fail=False):
++                 data=None, check_can_fail=False, fast=False):
+         """ Internal function, use .checkMD() from outside yum. """
+ 
+         thisdata = data # So the argument name is nicer
+@@ -1537,6 +1610,18 @@ class YumRepository(Repository, config.RepoConf):
+         if size is not None:
+             size = int(size)
+ 
++        if fast:
++            fsize = misc.stat_f(file)
++            if fsize is None: # File doesn't exist...
++                return None
++            if size is None:
++                return 1
++            if size == fsize.st_size:
++                return 1
++            if check_can_fail:
++                return None
++            raise URLGrabError(-1, 'Metadata file does not match size')
++
+         try: # get the local checksum
+             l_csum = self._checksum(r_ctype, file, datasize=size)
+         except Errors.RepoError, e:
+@@ -1551,15 +1636,13 @@ class YumRepository(Repository, config.RepoConf):
+                 return None
+             raise URLGrabError(-1, 'Metadata file does not match checksum')
+ 
+-
+-
+     def retrieveMD(self, mdtype):
+         """base function to retrieve metadata files from the remote url
+            returns the path to the local metadata file of a 'mdtype'
+            mdtype can be 'primary', 'filelists', 'other' or 'group'."""
+         return self._retrieveMD(mdtype)
+ 
+-    def _retrieveMD(self, mdtype, retrieve_can_fail=False):
++    def _retrieveMD(self, mdtype, retrieve_can_fail=False, **kwargs):
+         """ Internal function, use .retrieveMD() from outside yum. """
+         #  Note that this can raise Errors.RepoMDError if mdtype doesn't exist
+         # for this repo.
+@@ -1597,7 +1680,9 @@ class YumRepository(Repository, config.RepoConf):
+                 return local # it's the same return the local one
+ 
+         try:
+-            checkfunc = (self.checkMD, (mdtype,), {})
++            def checkfunc(obj):
++                self.checkMD(obj, mdtype)
++                self.retrieved[mdtype] = 1
+             text = "%s/%s" % (self.id, mdtype)
+             if thisdata.size is None:
+                 reget = None
+@@ -1613,8 +1698,9 @@ class YumRepository(Repository, config.RepoConf):
+                                   checkfunc=checkfunc, 
                                    text=text,
                                    cache=self.http_caching == 'all',
-                                   size=thisdata.size)
+-                                  size=thisdata.size)
 -        except (Errors.NoMoreMirrorsRepoError, Errors.RepoError):
++                                  size=thisdata.size,
++                                  **kwargs)
 +        except Errors.RepoError:
              if retrieve_can_fail:
                  return None
              raise
+@@ -1624,7 +1710,6 @@ class YumRepository(Repository, config.RepoConf):
+             raise Errors.RepoError, \
+                 "Could not retrieve %s matching remote checksum from %s" % (local, self)
+         else:
+-            self.retrieved[mdtype] = 1
+             return local
+ 
+ 
 diff --git a/yumcommands.py b/yumcommands.py
-index 4dcbea7..9c181ec 100644
+index 4dcbea7..bc30bd4 100644
 --- a/yumcommands.py
 +++ b/yumcommands.py
+@@ -29,7 +29,7 @@ import operator
+ import locale
+ import fnmatch
+ import time
+-from yum.i18n import utf8_width, utf8_width_fill, to_unicode
++from yum.i18n import utf8_width, utf8_width_fill, to_unicode, exception2msg
+ 
+ import yum.config
+ 
 @@ -43,16 +43,24 @@ def _err_mini_usage(base, basecmd):
      base.logger.critical(txt)
  
@@ -156981,7 +158173,7 @@ index 4dcbea7..9c181ec 100644
      """
      if base.repos.listEnabled():
          return
-@@ -152,85 +199,207 @@ def checkEnabledRepo(base, possible_local_files=[]):
+@@ -152,113 +199,273 @@ def checkEnabledRepo(base, possible_local_files=[]):
      raise cli.CliError
  
  class YumCommand:
@@ -157141,9 +158333,10 @@ index 4dcbea7..9c181ec 100644
 -            return base.installPkgs(extcmds)
 +            return base.installPkgs(extcmds, basecmd=basecmd)
          except yum.Errors.YumBaseError, e:
-             return 1, [str(e)]
- 
+-            return 1, [str(e)]
++            return 1, [exception2msg(e)]
 +
+ 
  class UpdateCommand(YumCommand):
 +    """A class containing methods needed by the cli to execute the
 +    update command.
@@ -157202,8 +158395,9 @@ index 4dcbea7..9c181ec 100644
          self.doneCommand(base, _("Setting up Update Process"))
          try:
              return base.updatePkgs(extcmds, update_to=(basecmd == 'update-to'))
-@@ -238,21 +407,59 @@ class UpdateCommand(YumCommand):
-             return 1, [str(e)]
+         except yum.Errors.YumBaseError, e:
+-            return 1, [str(e)]
++            return 1, [exception2msg(e)]
  
  class DistroSyncCommand(YumCommand):
 +    """A class containing methods needed by the cli to execute the
@@ -157262,7 +158456,14 @@ index 4dcbea7..9c181ec 100644
          self.doneCommand(base, _("Setting up Distribution Synchronization Process"))
          try:
              base.conf.obsoletes = 1
-@@ -289,18 +496,53 @@ def _list_cmd_calc_columns(base, ypl):
+             return base.distroSyncPkgs(extcmds)
+         except yum.Errors.YumBaseError, e:
+-            return 1, [str(e)]
++            return 1, [exception2msg(e)]
+ 
+ def _add_pkg_simple_list_lens(data, pkg, indent=''):
+     """ Get the length of each pkg's column. Add that to data.
+@@ -289,21 +496,56 @@ def _list_cmd_calc_columns(base, ypl):
      return (-columns[0], -columns[1], -columns[2])
  
  class InfoCommand(YumCommand):
@@ -157315,7 +158516,11 @@ index 4dcbea7..9c181ec 100644
 +                highlight = False
              ypl = base.returnPkgLists(extcmds, installed_available=highlight)
          except yum.Errors.YumBaseError, e:
-             return 1, [str(e)]
+-            return 1, [str(e)]
++            return 1, [exception2msg(e)]
+         else:
+             update_pkgs = {}
+             inst_pkgs   = {}
 @@ -341,6 +583,7 @@ class InfoCommand(YumCommand):
                          local_pkgs[(po.name, po.arch)] = po
  
@@ -157342,7 +158547,7 @@ index 4dcbea7..9c181ec 100644
                                                   '=' : clar, 'not in' : clai})
              rep = base.listPkgs(ypl.extras, _('Extra Packages'), basecmd,
                                  columns=columns)
-@@ -389,35 +635,95 @@ class InfoCommand(YumCommand):
+@@ -389,45 +635,121 @@ class InfoCommand(YumCommand):
              return 0, []
  
      def needTs(self, base, basecmd, extcmds):
@@ -157438,8 +158643,9 @@ index 4dcbea7..9c181ec 100644
          self.doneCommand(base, _("Setting up Remove Process"))
          try:
              return base.erasePkgs(extcmds)
-@@ -425,9 +731,25 @@ class EraseCommand(YumCommand):
-             return 1, [str(e)]
+         except yum.Errors.YumBaseError, e:
+-            return 1, [str(e)]
++            return 1, [exception2msg(e)]
  
      def needTs(self, base, basecmd, extcmds):
 +        """Return whether a transaction set must be set up before this
@@ -157490,6 +158696,15 @@ index 4dcbea7..9c181ec 100644
          return _("Display, or use, the groups information")
      
      def _grp_setup_doCommand(self, base):
+@@ -459,7 +794,7 @@ class GroupsCommand(YumCommand):
+         except yum.Errors.GroupsError:
+             return 1, [_('No Groups on which to run command')]
+         except yum.Errors.YumBaseError, e:
+-            return 1, [str(e)]
++            return 1, [exception2msg(e)]
+ 
+     def _grp_cmd(self, basecmd, extcmds):
+         if basecmd in self.direct_commands:
 @@ -470,6 +805,10 @@ class GroupsCommand(YumCommand):
          else:
              cmd = 'summary'
@@ -157689,7 +158904,8 @@ index 4dcbea7..9c181ec 100644
 +
 +
          except yum.Errors.YumBaseError, e:
-             return 1, [str(e)]
+-            return 1, [str(e)]
++            return 1, [exception2msg(e)]
  
  
      def needTs(self, base, basecmd, extcmds):
@@ -157779,7 +158995,14 @@ index 4dcbea7..9c181ec 100644
          base.logger.debug(_("Making cache files for all metadata files."))
          base.logger.debug(_("This may take a while depending on the speed of this computer"))
          try:
-@@ -572,9 +1105,7 @@ class MakeCacheCommand(YumCommand):
+@@ -565,81 +1098,204 @@ class MakeCacheCommand(YumCommand):
+                 repo.mdpolicy = "group:all"
+             base.doRepoSetup(dosack=0)
+             base.repos.doSetup()
+-            for repo in base.repos.listEnabled():
+-                repo.repoXML
+             
+             # These convert the downloaded data into usable data,
              # we can't remove them until *LoadRepo() can do:
              # 1. Download a .sqlite.bz2 and convert to .sqlite
              # 2. Download a .xml.gz and convert to .xml.gz.sqlite
@@ -157790,7 +159013,8 @@ index 4dcbea7..9c181ec 100644
  
  
          except yum.Errors.YumBaseError, e:
-@@ -582,44 +1113,134 @@ class MakeCacheCommand(YumCommand):
+-            return 1, [str(e)]
++            return 1, [exception2msg(e)]
          return 0, [_('Metadata Cache Created')]
  
      def needTs(self, base, basecmd, extcmds):
@@ -157925,8 +159149,9 @@ index 4dcbea7..9c181ec 100644
          base.logger.debug("Searching Packages: ")
          try:
              return base.provides(extcmds)
-@@ -627,19 +1248,56 @@ class ProvidesCommand(YumCommand):
-             return 1, [str(e)]
+         except yum.Errors.YumBaseError, e:
+-            return 1, [str(e)]
++            return 1, [exception2msg(e)]
  
  class CheckUpdateCommand(YumCommand):
 +    """A class containing methods needed by the cli to execute the
@@ -157982,7 +159207,13 @@ index 4dcbea7..9c181ec 100644
          obscmds = ['obsoletes'] + extcmds
          base.extcmds.insert(0, 'updates')
          result = 0
-@@ -681,19 +1339,56 @@ class CheckUpdateCommand(YumCommand):
+@@ -676,161 +1332,437 @@ class CheckUpdateCommand(YumCommand):
+                                               columns=columns)
+                 result = 100
+         except yum.Errors.YumBaseError, e:
+-            return 1, [str(e)]
++            return 1, [exception2msg(e)]
+         else:
              return result, []
  
  class SearchCommand(YumCommand):
@@ -158039,8 +159270,9 @@ index 4dcbea7..9c181ec 100644
          base.logger.debug(_("Searching Packages: "))
          try:
              return base.search(extcmds)
-@@ -701,24 +1396,70 @@ class SearchCommand(YumCommand):
-             return 1, [str(e)]
+         except yum.Errors.YumBaseError, e:
+-            return 1, [str(e)]
++            return 1, [exception2msg(e)]
  
      def needTs(self, base, basecmd, extcmds):
 +        """Return whether a transaction set must be set up before this
@@ -158110,8 +159342,10 @@ index 4dcbea7..9c181ec 100644
          base.conf.obsoletes = 1
          self.doneCommand(base, _("Setting up Upgrade Process"))
          try:
-@@ -727,25 +1468,64 @@ class UpgradeCommand(YumCommand):
-             return 1, [str(e)]
+             return base.updatePkgs(extcmds, update_to=(basecmd == 'upgrade-to'))
+         except yum.Errors.YumBaseError, e:
+-            return 1, [str(e)]
++            return 1, [exception2msg(e)]
  
  class LocalInstallCommand(YumCommand):
 +    """A class containing methods needed by the cli to execute the
@@ -158175,8 +159409,11 @@ index 4dcbea7..9c181ec 100644
          self.doneCommand(base, _("Setting up Local Package Process"))
  
          updateonly = basecmd == 'localupdate'
-@@ -755,19 +1535,61 @@ class LocalInstallCommand(YumCommand):
-             return 1, [str(e)]
+         try:
+             return base.localInstall(filelist=extcmds, updateonly=updateonly)
+         except yum.Errors.YumBaseError, e:
+-            return 1, [str(e)]
++            return 1, [exception2msg(e)]
  
      def needTs(self, base, basecmd, extcmds):
 +        """Return whether a transaction set must be set up before this
@@ -158238,8 +159475,9 @@ index 4dcbea7..9c181ec 100644
          base.logger.debug(_("Searching Packages for Dependency:"))
          try:
              return base.resolveDepCli(extcmds)
-@@ -775,19 +1597,56 @@ class ResolveDepCommand(YumCommand):
-             return 1, [str(e)]
+         except yum.Errors.YumBaseError, e:
+-            return 1, [str(e)]
++            return 1, [exception2msg(e)]
  
  class ShellCommand(YumCommand):
 +    """A class containing methods needed by the cli to execute the
@@ -158295,8 +159533,9 @@ index 4dcbea7..9c181ec 100644
          self.doneCommand(base, _('Setting up Yum Shell'))
          try:
              return base.doShell()
-@@ -795,23 +1654,69 @@ class ShellCommand(YumCommand):
-             return 1, [str(e)]
+         except yum.Errors.YumBaseError, e:
+-            return 1, [str(e)]
++            return 1, [exception2msg(e)]
  
      def needTs(self, base, basecmd, extcmds):
 +        """Return whether a transaction set must be set up before this
@@ -158365,7 +159604,9 @@ index 4dcbea7..9c181ec 100644
          self.doneCommand(base, _("Finding dependencies: "))
          try:
              return base.deplist(extcmds)
-@@ -820,17 +1725,46 @@ class DepListCommand(YumCommand):
+         except yum.Errors.YumBaseError, e:
+-            return 1, [str(e)]
++            return 1, [exception2msg(e)]
  
  
  class RepoListCommand(YumCommand):
@@ -158412,7 +159653,7 @@ index 4dcbea7..9c181ec 100644
          def _repo_size(repo):
              ret = 0
              for pkg in repo.sack.returnPackages():
-@@ -866,6 +1800,13 @@ class RepoListCommand(YumCommand):
+@@ -866,6 +1798,13 @@ class RepoListCommand(YumCommand):
              except yum.Errors.RepoError:
                  if verbose:
                      raise
@@ -158426,7 +159667,7 @@ index 4dcbea7..9c181ec 100644
  
          repos = base.repos.repos.values()
          repos.sort()
-@@ -924,111 +1865,108 @@ class RepoListCommand(YumCommand):
+@@ -924,111 +1863,108 @@ class RepoListCommand(YumCommand):
                  ui_enabled = dhibeg + _('disabled') + hiend
                  ui_endis_wid = utf8_width(_('disabled'))
  
@@ -158631,7 +159872,7 @@ index 4dcbea7..9c181ec 100644
  
          if not verbose and cols:
              #  Work out the first (id) and last (enabled/disalbed/count),
-@@ -1088,21 +2026,54 @@ class RepoListCommand(YumCommand):
+@@ -1088,21 +2024,54 @@ class RepoListCommand(YumCommand):
          return 0, ['repolist: ' +to_unicode(locale.format("%d", tot_num, True))]
  
      def needTs(self, base, basecmd, extcmds):
@@ -158686,7 +159927,7 @@ index 4dcbea7..9c181ec 100644
          if len(extcmds) == 0:
              base.usage()
              raise cli.CliError
-@@ -1147,28 +2118,85 @@ class HelpCommand(YumCommand):
+@@ -1147,28 +2116,85 @@ class HelpCommand(YumCommand):
          return help_output
  
      def doCommand(self, base, basecmd, extcmds):
@@ -158772,7 +160013,7 @@ index 4dcbea7..9c181ec 100644
          self.doneCommand(base, _("Setting up Reinstall Process"))
          try:
              return base.reinstallPkgs(extcmds)
-@@ -1177,25 +2205,73 @@ class ReInstallCommand(YumCommand):
+@@ -1177,49 +2203,139 @@ class ReInstallCommand(YumCommand):
              return 1, [to_unicode(e)]
  
      def getSummary(self):
@@ -158846,8 +160087,9 @@ index 4dcbea7..9c181ec 100644
          self.doneCommand(base, _("Setting up Downgrade Process"))
          try:
              return base.downgradePkgs(extcmds)
-@@ -1203,23 +2279,65 @@ class DowngradeCommand(YumCommand):
-             return 1, [str(e)]
+         except yum.Errors.YumBaseError, e:
+-            return 1, [str(e)]
++            return 1, [exception2msg(e)]
  
      def getSummary(self):
 +        """Return a one line summary of this command.
@@ -158912,7 +160154,25 @@ index 4dcbea7..9c181ec 100644
          vcmd = 'installed'
          if extcmds:
              vcmd = extcmds[0]
-@@ -1344,6 +2462,14 @@ class VersionCommand(YumCommand):
+@@ -1308,7 +2424,7 @@ class VersionCommand(YumCommand):
+                                      str(data[2][grp])))
+                         _append_repos(cols, data[3][grp])
+             except yum.Errors.YumBaseError, e:
+-                return 1, [str(e)]
++                return 1, [exception2msg(e)]
+         if vcmd in ('available', 'all', 'group-available', 'group-all'):
+             try:
+                 data = base.pkgSack.simpleVersion(not verbose, groups=groups)
+@@ -1327,7 +2443,7 @@ class VersionCommand(YumCommand):
+                         if verbose:
+                             _append_repos(cols, data[3][grp])
+             except yum.Errors.YumBaseError, e:
+-                return 1, [str(e)]
++                return 1, [exception2msg(e)]
+ 
+         data = {'rid' : {}, 'ver' : {}}
+         for (rid, ver) in cols:
+@@ -1344,6 +2460,14 @@ class VersionCommand(YumCommand):
          return 0, ['version']
  
      def needTs(self, base, basecmd, extcmds):
@@ -158927,7 +160187,7 @@ index 4dcbea7..9c181ec 100644
          vcmd = 'installed'
          if extcmds:
              vcmd = extcmds[0]
-@@ -1354,23 +2480,62 @@ class VersionCommand(YumCommand):
+@@ -1354,23 +2478,62 @@ class VersionCommand(YumCommand):
  
  
  class HistoryCommand(YumCommand):
@@ -158991,7 +160251,7 @@ index 4dcbea7..9c181ec 100644
              return 2, ["Repeating transaction %u" % (old.tid,)]
  
      def _hcmd_undo(self, base, extcmds):
-@@ -1426,12 +2591,54 @@ class HistoryCommand(YumCommand):
+@@ -1426,12 +2589,57 @@ class HistoryCommand(YumCommand):
      def _hcmd_new(self, base, extcmds):
          base.history._create_db_file()
  
@@ -158999,9 +160259,12 @@ index 4dcbea7..9c181ec 100644
 +        print "File        :", base.history._db_file
 +        num = os.stat(base.history._db_file).st_size
 +        print "Size        :", locale.format("%d", num, True)
++        trans_N = base.history.last()
++        if trans_N is None:
++            print _("Transactions:"), 0
++            return
 +        counts = base.history._pkg_stats()
 +        trans_1 = base.history.old("1")[0]
-+        trans_N = base.history.last()
 +        print _("Transactions:"), trans_N.tid
 +        print _("Begin time  :"), time.ctime(trans_1.beg_timestamp)
 +        print _("End time    :"), time.ctime(trans_N.end_timestamp)
@@ -159047,7 +160310,7 @@ index 4dcbea7..9c181ec 100644
          if extcmds and extcmds[0] not in cmds:
              base.logger.critical(_('Invalid history sub-command, use: %s.'),
                                   ", ".join(cmds))
-@@ -1444,6 +2651,19 @@ class HistoryCommand(YumCommand):
+@@ -1444,6 +2652,19 @@ class HistoryCommand(YumCommand):
              raise cli.CliError
  
      def doCommand(self, base, basecmd, extcmds):
@@ -159067,7 +160330,7 @@ index 4dcbea7..9c181ec 100644
          vcmd = 'list'
          if extcmds:
              vcmd = extcmds[0]
-@@ -1468,12 +2688,26 @@ class HistoryCommand(YumCommand):
+@@ -1468,12 +2689,26 @@ class HistoryCommand(YumCommand):
              ret = self._hcmd_rollback(base, extcmds)
          elif vcmd == 'new':
              ret = self._hcmd_new(base, extcmds)
@@ -159094,7 +160357,7 @@ index 4dcbea7..9c181ec 100644
          vcmd = 'list'
          if extcmds:
              vcmd = extcmds[0]
-@@ -1481,16 +2715,46 @@ class HistoryCommand(YumCommand):
+@@ -1481,16 +2716,46 @@ class HistoryCommand(YumCommand):
  
  
  class CheckRpmdbCommand(YumCommand):
@@ -159141,7 +160404,7 @@ index 4dcbea7..9c181ec 100644
          chkcmd = 'all'
          if extcmds:
              chkcmd = extcmds
-@@ -1505,19 +2769,57 @@ class CheckRpmdbCommand(YumCommand):
+@@ -1505,19 +2770,57 @@ class CheckRpmdbCommand(YumCommand):
          return rc, ['%s %s' % (basecmd, chkcmd)]
  
      def needTs(self, base, basecmd, extcmds):
@@ -159199,7 +160462,7 @@ index 4dcbea7..9c181ec 100644
          if not extcmds:
              base.logger.critical(_("No saved transaction file specified."))
              raise cli.CliError
-@@ -1533,5 +2835,13 @@ class LoadTransactionCommand(YumCommand):
+@@ -1533,5 +2836,13 @@ class LoadTransactionCommand(YumCommand):
  
  
      def needTs(self, base, basecmd, extcmds):
@@ -159214,7 +160477,7 @@ index 4dcbea7..9c181ec 100644
          return True
  
 diff --git a/yummain.py b/yummain.py
-index 9f79f4f..c473df6 100755
+index 9f79f4f..e3a232b 100755
 --- a/yummain.py
 +++ b/yummain.py
 @@ -29,13 +29,13 @@ from yum import Errors
@@ -159234,21 +160497,19 @@ index 9f79f4f..c473df6 100755
  
      yum.misc.setup_locale(override_time=True)
  
-@@ -102,15 +102,21 @@ def main(args):
-         return exFatal(e)
+@@ -89,6 +89,23 @@ def main(args):
+     logger = logging.getLogger("yum.main")
+     verbose_logger = logging.getLogger("yum.verbose.main")
  
-     # Try to open the current directory to see if we have 
--    # read and write access. If not, chdir to /
++    # Try to open the current directory to see if we have 
 +    # read and execute access. If not, chdir to /
-     try:
-         f = open(".")
-     except IOError, e:
-         if e.errno == errno.EACCES:
--            logger.critical(_('No read/write access in current directory, moving to /'))
++    try:
++        f = open(".")
++    except IOError, e:
++        if e.errno == errno.EACCES:
 +            logger.critical(_('No read/execute access in current directory, moving to /'))
-             os.chdir("/")
-     else:
--        close(f)
++            os.chdir("/")
++    else:
 +        f.close()
 +    try:
 +        os.getcwd()
@@ -159256,9 +160517,28 @@ index 9f79f4f..c473df6 100755
 +        if e.errno == errno.ENOENT:
 +            logger.critical(_('No getcwd() access in current directory, moving to /'))
 +            os.chdir("/")
++
+     # our core object for the cli
+     base = cli.YumBaseCli()
+ 
+@@ -101,17 +118,6 @@ def main(args):
+     except Errors.YumBaseError, e:
+         return exFatal(e)
  
+-    # Try to open the current directory to see if we have 
+-    # read and write access. If not, chdir to /
+-    try:
+-        f = open(".")
+-    except IOError, e:
+-        if e.errno == errno.EACCES:
+-            logger.critical(_('No read/write access in current directory, moving to /'))
+-            os.chdir("/")
+-    else:
+-        close(f)
+-
      lockerr = ""
      while True:
+         try:
 @@ -120,16 +126,16 @@ def main(args):
              if exception2msg(e) != lockerr:
                  lockerr = exception2msg(e)
diff --git a/yum-ppc64-preferred.patch b/yum-ppc64-preferred.patch
index 6c84924..3eaae57 100644
--- a/yum-ppc64-preferred.patch
+++ b/yum-ppc64-preferred.patch
@@ -2,8 +2,8 @@ diff -ru yum-3.4.3-orig/rpmUtils/arch.py yum-3.4.3/rpmUtils/arch.py
 --- yum-3.4.3-orig/rpmUtils/arch.py	2011-06-28 17:01:10.009680846 -0400
 +++ yum-3.4.3/rpmUtils/arch.py	2011-06-28 17:01:31.849916539 -0400
 @@ -3,7 +3,7 @@
- import os
- import rpm
+ import ctypes
+ import struct
  
 -_ppc64_native_is_best = False
 +_ppc64_native_is_best = True
diff --git a/yum.spec b/yum.spec
index d4cc3f5..5ad02fe 100644
--- a/yum.spec
+++ b/yum.spec
@@ -18,7 +18,7 @@
 Summary: RPM package installer/updater/manager
 Name: yum
 Version: 3.4.3
-Release: 25%{?dist}
+Release: 26%{?dist}
 License: GPLv2+
 Group: System Environment/Base
 Source0: http://yum.baseurl.org/download/3.4/%{name}-%{version}.tar.gz
@@ -30,9 +30,7 @@ Patch5: geode-arch.patch
 Patch6: yum-HEAD.patch
 Patch7: yum-ppc64-preferred.patch
 Patch8: BZ-803346-no-only-update.patch
-Patch9: arm-arch-detection.patch
 Patch20: yum-manpage-files.patch
-Patch21: BZ-809469-completion-helper.patch
 
 URL: http://yum.baseurl.org/
 BuildArchitectures: noarch
@@ -140,9 +138,7 @@ Install this package if you want auto yum updates nightly via cron.
 %patch6 -p1
 %patch7 -p1
 %patch8 -p1
-%patch9 -p1
 %patch20 -p1
-%patch21 -p1
 %patch1 -p1
 
 %build
@@ -296,7 +292,7 @@ exit 0
 %files cron
 %defattr(-,root,root)
 %doc COPYING
-%config(noreplace) %{_sysconfdir}/cron.daily/yum-update.cron
+%config(noreplace) %{_sysconfdir}/cron.daily/0yum-update.cron
 %config(noreplace) %{_sysconfdir}/cron.daily/yum-cleanup.cron
 %{_sysconfdir}/rc.d/init.d/yum-cron
 %{_sbindir}/yum-cron
@@ -317,6 +313,12 @@ exit 0
 %endif
 
 %changelog
+* Thu Jun  7 2012 Zdenek Pavlas <zpavlas at redhat.com> - 3.4.3-26
+- update to latest HEAD
+- more completion helper patches
+- parallel downloading of packages and metadata
+- revert a hack that probably caused BZ 829505
+
 * Thu May 31 2012 Zdenek Pavlas <zpavlas at redhat.com> - 3.4.3-25
 - backported completion-helper.py patches from HEAD, BZ 809469.
 


More information about the scm-commits mailing list