Merged from trunk 11187:11200
authorFabian Groffen <grobian@gentoo.org>
Sat, 26 Jul 2008 20:55:16 +0000 (20:55 -0000)
committerFabian Groffen <grobian@gentoo.org>
Sat, 26 Jul 2008 20:55:16 +0000 (20:55 -0000)
   | 11188   | Detect an invalid cpv passed into portdbapi.findname2() and  |
   | zmedico | raise an InvalidPackageName exception. This avoids silent or |
   |         | nonsense errors later on.                                    |

   | 11190   | Fix PORTAGE_BIN_PATH typo in EbuildFetcher._start().         |
   | zmedico |                                                              |

   | 11191   | Suppress "for /" and "to /" in status messages when ROOT=/.  |
   | zmedico | Thanks to Thargor for the suggestion.                        |

   | 11192   | Add PORTAGE_IONICE_COMMAND setting for make.conf which is    |
   | zmedico | called to adjust IO priority on portage and it's             |
   |         | subprocesses.                                                |

   | 11193   | Reduce the default PORTAGE_IONICE_COMMAND priority to "idle" |
   | zmedico | priority since it's probably suitable for most people. This  |
   |         | way, even when the IO load is very high, the impact on       |
   |         | system responsiveness should be practically unnoticeable.    |

   | 11194   | * For bug 227625, automatically create the                   |
   | zmedico | /usr/src/rpm/SOURCES directory when necessary. * Add `cd     |
   |         | "${T}"` at the beginning of dyn_rpm() since the spec file is |
   |         | written to $PWD.                                             |

   | 11195   | Replace hardcoded i386 machine name in dyn_rpm() with the    |
   | zmedico | result of `uname -m`.                                        |

   | 11196   | Bug #228085 - In the event of a file collision, the          |
   | zmedico | explanation about the collision and how to solve it may not  |
   |         | be visible via a scrollback buffer, especially if the number |
   |         | of file collisions is large. Therefore, show a summary at    |
   |         | the end and refer the user to the elog messages.             |

   | 11197   | Bug #232924 - When the user specifies a non-existent set,    |
   | zmedico | display a list of existing sets.                             |

   | 11198   | Split out an apply_priorities() function to apply nice and   |
   | zmedico | ionice settings.                                             |

   | 11199   | * Use pure bash ${PARAMETER%/*} instead of spawing`dirname`. |
   | zmedico | * Break out of loop as early as possible when searching for  |
   |         | libs in ${D}.                                                |

   | 11200   | Fix LinkageMap.findConsumers() to check whether the master   |
   | zmedico | link for a lib providing a given soname actually points to   |
   |         | that lib. If there is another version of this lib with the   |
   |         | same soname and the master link points to that other         |
   |         | version, this lib will be shadowed and won't have any        |
   |         | consumers. By eliminating false, positives this way, we      |
   |         | avoid the following state after upgrade from                 |
   |         | media-libs/mesa-7.0.3 to media-libs/mesa-7.1_rc3: # scanelf  |
   |         | -S /usr/lib64/libGLU.so* TYPE SONAME FILE ET_DYN libGLU.so.1 |
   |         | /usr/lib64/libGLU.so ET_DYN libGLU.so.1                      |
   |         | /usr/lib64/libGLU.so.1 ET_DYN libGLU.so.1                    |
   |         | /usr/lib64/libGLU.so.1.3 ET_DYN libGLU.so.1                  |
   |         | /usr/lib64/libGLU.so.1.3.070003 ET_DYN libGLU.so.1           |
   |         | /usr/lib64/libGLU.so.1.3.070100 <- shadowed lib Thanks to    |
   |         | Diego "Flameeyes" Pettenò for reporting this issue.         |

svn path=/main/branches/prefix/; revision=11201

NEWS
bin/misc-functions.sh
cnf/make.globals
man/make.conf.5
pym/_emerge/__init__.py
pym/portage/dbapi/porttree.py
pym/portage/dbapi/vartree.py
pym/portage/exception.py

diff --git a/NEWS b/NEWS
index 2fb033c0b6f75d9c52ef0b415ce58f5945542ebd..4c565a514fa4473c6f1a40810cdffbbba956f460 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -3,6 +3,8 @@ News (mainly features/major bug fixes)
 portage-2.2
 -------------
 
+* Add PORTAGE_IONICE_COMMAND setting for make.conf which is called to adjust
+  IO priority on portage and it's subprocesses.
 * Add link level dependency awareness to emerge --depclean and --prune actions
   in order to protect against uninstallation of required libraries.
 * Add emerge --jobs and --load-average options which specify behavior
index 5e3644771e093e1101f934286e375a0a0891c08b..21bce35cb7f95a6f9da15999e19dd0678194aabb 100644 (file)
@@ -170,7 +170,7 @@ install_qa_check() {
                                echo "${obj} ${needed}" >> "${PORTAGE_BUILDDIR}"/build-info/NEEDED
                                echo "${arch:3};${obj};${soname};${rpath};${needed}" >> "${PORTAGE_BUILDDIR}"/build-info/NEEDED.ELF.2
                        else
-                               dir=$(dirname ${obj})
+                               dir=${obj%/*}
                                # replace $ORIGIN with the dirname of the current object for the lookup
                                opath=$(echo :${rpath}: | sed -e "s#.*:\(.*\)\$ORIGIN\(.*\):.*#\1${dir}\2#")
                                sneeded=$(echo ${needed} | tr , ' ')
@@ -178,7 +178,7 @@ install_qa_check() {
                                for lib in ${sneeded}; do
                                        found=0
                                        for path in ${opath//:/ }; do
-                                               [ -e "${D}/${path}/${lib}" ] && found=1
+                                               [ -e "${D}/${path}/${lib}" ] && found=1 && break
                                        done
                                        [ "${found}" -eq 0 ] && rneeded="${rneeded},${lib}"
                                done
@@ -731,7 +731,9 @@ dyn_package() {
 }
 
 dyn_spec() {
-       tar czf "/usr/src/rpm/SOURCES/${PF}.tar.gz" \
+       local sources_dir=/usr/src/rpm/SOURCES
+       mkdir -p "${sources_dir}"
+       tar czf "${sources_dir}/${PF}.tar.gz" \
                "${EBUILD}" "${FILESDIR}" || \
                die "Failed to create base rpm tarball."
 
@@ -765,11 +767,14 @@ __END1__
 }
 
 dyn_rpm() {
+       cd "${T}" || die "cd failed"
+       local machine_name=$(uname -m)
+       local dest_dir=/usr/src/rpm/RPMS/${machine_name}
        addwrite /usr/src/rpm
        addwrite "${RPMDIR}"
        dyn_spec
        rpmbuild -bb --clean --rmsource "${PF}.spec" || die "Failed to integrate rpm spec file"
-       install -D "/usr/src/rpm/RPMS/i386/${PN}-${PV}-${PR}.i386.rpm" \
+       install -D "${dest_dir}/${PN}-${PV}-${PR}.${machine_name}.rpm" \
                "${RPMDIR}/${CATEGORY}/${PN}-${PV}-${PR}.rpm" || \
                die "Failed to move rpm"
 }
index 06a28bbf48018ea7b1d65a6d23ccfddc91225a7b..016810a9fd2a3dab40a49bc22884aa8cf4a06580 100644 (file)
@@ -63,7 +63,7 @@ PORTAGE_FETCH_CHECKSUM_TRY_MIRRORS="5"
 PORTAGE_FETCH_RESUME_MIN_SIZE="350K"
 
 # Command called to adjust the io priority of portage and it's subprocesses.
-PORTAGE_IONICE_COMMAND="ionice -c 2 -n 7 -p \${PID}"
+PORTAGE_IONICE_COMMAND="ionice -c 3 -p \${PID}"
 
 # Number of times 'emerge --sync' will run before giving up.
 PORTAGE_RSYNC_RETRIES="3"
index 875060da2dc0ae216ebd50c9075cfbd472ef570d..4c291c0da42af8070f4d582c96bb304a24952902 100644 (file)
@@ -467,7 +467,7 @@ with an integer pid. For more information about ionice, see \fBionice\fR(1).
 Set this variable to an empty string if you do not want portage to call
 ionice.
 .br
-Defaults to "ionice -c 2 -n 7 -p \\${PID}".
+Defaults to "ionice -c 3 -p \\${PID}".
 .TP
 \fBPORTAGE_NICENESS\fR = \fI[number]\fR
 The value of this variable will be added to the current nice level that
index a60820c245a4020f78f0aa37bda3b37ff37619d9..2fbc8b4e275a3c4003bd67946e47a84ce3db4e14 100644 (file)
@@ -2258,7 +2258,7 @@ class EbuildFetcher(SpawnProcess):
                        fetch_env["PORTAGE_PARALLEL_FETCHONLY"] = "1"
 
                ebuild_binary = os.path.join(
-                       settings["EBUILD_BIN_PATH"], "ebuild")
+                       settings["PORTAGE_BIN_PATH"], "ebuild")
 
                fetch_args = [ebuild_binary, ebuild_path, "fetch"]
                debug = settings.get("PORTAGE_DEBUG") == "1"
@@ -3406,14 +3406,17 @@ class MergeListItem(CompositeTask):
                if build_opts.fetchonly:
                        action_desc = "Fetching"
 
-               if not build_opts.pretend:
+               msg = "%s (%s of %s) %s" % \
+                       (action_desc,
+                       colorize("MERGE_LIST_PROGRESS", str(pkg_count.curval)),
+                       colorize("MERGE_LIST_PROGRESS", str(pkg_count.maxval)),
+                       colorize("GOOD", pkg.cpv))
 
-                       self.statusMessage("%s (%s of %s) %s %s %s" % \
-                               (action_desc,
-                               colorize("MERGE_LIST_PROGRESS", str(pkg_count.curval)),
-                               colorize("MERGE_LIST_PROGRESS", str(pkg_count.maxval)),
-                               colorize("GOOD", pkg.cpv), preposition, pkg.root))
+               if pkg.root != "/":
+                       msg += " %s %s" % (preposition, pkg.root)
 
+               if not build_opts.pretend:
+                       self.statusMessage(msg)
                        logger.log(" >>> emerge (%s of %s) %s to %s" % \
                                (pkg_count.curval, pkg_count.maxval, pkg.cpv, pkg.root))
 
@@ -3514,12 +3517,15 @@ class PackageMerge(AsynchronousTask):
                        action_desc = "Installing"
                        preposition = "to"
 
+               msg = "%s %s" % (action_desc, colorize("GOOD", pkg.cpv))
+
+               if pkg.root != "/":
+                       msg += " %s %s" % (preposition, pkg.root)
+
                if not self.merge.build_opts.fetchonly and \
                        not self.merge.build_opts.pretend and \
                        not self.merge.build_opts.buildpkgonly:
-                       self.merge.statusMessage("%s %s %s %s" % \
-                               (action_desc, colorize("GOOD", pkg.cpv),
-                               preposition, pkg.root))
+                       self.merge.statusMessage(msg)
 
                self.returncode = self.merge.merge()
                self.wait()
@@ -4795,8 +4801,7 @@ class depgraph(object):
                                if x.startswith(SETPREFIX):
                                        s = x[len(SETPREFIX):]
                                        if s not in sets:
-                                               raise portage.exception.PackageNotFound(
-                                                       "emerge: there are no sets to satisfy '%s'." % s)
+                                               raise portage.exception.PackageSetNotFound(s)
                                        if s in self._sets:
                                                continue
                                        # Recursively expand sets so that containment tests in
@@ -12511,6 +12516,10 @@ def action_build(settings, trees, mtimedb,
                except portage.exception.PackageNotFound, e:
                        portage.writemsg("\n!!! %s\n" % str(e), noiselevel=-1)
                        return 1
+               except portage.exception.PackageSetNotFound, e:
+                       root_config = trees[settings["ROOT"]]["root_config"]
+                       display_missing_pkg_set(root_config, e.value)
+                       return 1
                if show_spinner:
                        print "\b\b... done!"
                if not retval:
@@ -12974,6 +12983,19 @@ def adjust_config(myopts, settings):
                settings["NOCOLOR"] = "true"
                settings.backup_changes("NOCOLOR")
 
+def apply_priorities(settings):
+       ionice(settings)
+       nice(settings)
+
+def nice(settings):
+       try:
+               os.nice(int(settings.get("PORTAGE_NICENESS", "0")))
+       except (OSError, ValueError), e:
+               out = portage.output.EOutput()
+               out.eerror("Failed to change nice value to '%s'" % \
+                       settings["PORTAGE_NICENESS"])
+               out.eerror("%s\n" % str(e))
+
 def ionice(settings):
 
        ionice_cmd = settings.get("PORTAGE_IONICE_COMMAND")
@@ -12998,6 +13020,21 @@ def ionice(settings):
                out.eerror("PORTAGE_IONICE_COMMAND returned %d" % (rval,))
                out.eerror("See the make.conf(5) man page for PORTAGE_IONICE_COMMAND usage instructions.")
 
+def display_missing_pkg_set(root_config, set_name):
+
+       msg = []
+       msg.append(("emerge: There are no sets to satisfy '%s'. " + \
+               "The following sets exist:") % \
+               colorize("INFORM", set_name))
+       msg.append("")
+
+       for s in sorted(root_config.sets):
+               msg.append("    %s" % s)
+       msg.append("")
+
+       writemsg_level("".join("%s\n" % l for l in msg),
+               level=logging.ERROR, noiselevel=-1)
+
 def emerge_main():
        global portage  # NFC why this is necessary now - genone
        portage._disable_legacy_globals()
@@ -13019,16 +13056,6 @@ def emerge_main():
        settings, trees, mtimedb = load_emerge_config()
        portdb = trees[settings["ROOT"]]["porttree"].dbapi
 
-       ionice(settings)
-
-       try:
-               os.nice(int(settings.get("PORTAGE_NICENESS", "0")))
-       except (OSError, ValueError), e:
-               portage.writemsg("!!! Failed to change nice value to '%s'\n" % \
-                       settings["PORTAGE_NICENESS"])
-               portage.writemsg("!!! %s\n" % str(e))
-               del e
-
        if portage._global_updates(trees, mtimedb["updates"]):
                mtimedb.commit()
                # Reload the whole config from scratch.
@@ -13057,6 +13084,8 @@ def emerge_main():
                mysettings.lock()
                del myroot, mysettings
 
+       apply_priorities(settings)
+
        spinner = stdout_spinner()
        if "candy" in settings.features:
                spinner.update = spinner.update_scroll
@@ -13176,8 +13205,7 @@ def emerge_main():
                        if a.startswith(SETPREFIX):
                                s = a[len(SETPREFIX):]
                                if s not in sets:
-                                       print "emerge: there are no sets to satisfy %s." % \
-                                               colorize("INFORM", s)
+                                       display_missing_pkg_set(root_config, s)
                                        return 1
                                setconfig.active.append(s)
                                if myaction in unmerge_actions and \
index 23fb67d32afb60e20fbfe6d80f7222532bfe92f2..872621e182d49a249939dda7a5441d901b65eb9d 100644 (file)
@@ -11,7 +11,7 @@ from portage.dep import use_reduce, paren_reduce, dep_getslot, dep_getkey, \
        match_from_list, match_to_list, remove_slot
 from portage.exception import OperationNotPermitted, PortageException, \
        UntrustedSignature, SecurityViolation, InvalidSignature, MissingSignature, \
-       FileNotFound, InvalidDependString
+       FileNotFound, InvalidDependString, InvalidPackageName
 from portage.manifest import Manifest
 from portage.output import red
 from portage.util import ensure_dirs, writemsg, apply_recursive_permissions
@@ -216,6 +216,8 @@ class portdbapi(dbapi):
                        return "",0
                mysplit = mycpv.split("/")
                psplit = pkgsplit(mysplit[1])
+               if psplit is None or len(mysplit) != 2:
+                       raise InvalidPackageName(mycpv)
 
                if mytree:
                        mytrees = [mytree]
index 4b648a915a7970b64509c6b672064d1d147d385a..1f8ee15f8e2af36f960c2f234866afaaa27128c5 100644 (file)
@@ -264,6 +264,24 @@ class LinkageMap(object):
                        obj = realpath(obj)
                        if obj not in self._obj_properties:
                                raise KeyError("%s not in object list" % obj)
+
+               # If there is another version of this lib with the
+               # same soname and the master link points to that
+               # other version, this lib will be shadowed and won't
+               # have any consumers.
+               arch, needed, path, soname = self._obj_properties[obj]
+               obj_dir = os.path.dirname(obj)
+               master_link = os.path.join(obj_dir, soname)
+               try:
+                       master_st = os.stat(master_link)
+                       obj_st = os.stat(obj)
+               except OSError:
+                       pass
+               else:
+                       if (obj_st.st_dev, obj_st.st_ino) != \
+                               (master_st.st_dev, master_st.st_ino):
+                               return set()
+
                rValue = set()
                for soname in self._libs:
                        for arch in self._libs[soname]:
@@ -273,7 +291,7 @@ class LinkageMap(object):
                                                path = [realpath(y) for y in path+self._defpath]
                                                if soname[0] == os.sep and realpath(soname) == realpath(obj):
                                                        rValue.add(x)
-                                               elif realpath(os.path.dirname(obj)) in path:
+                                               elif realpath(obj_dir) in path:
                                                        rValue.add(x)
                return rValue
                                        
@@ -2798,10 +2816,23 @@ class dblink(object):
                                for f in sorted(owned_files):
                                        msg.append("\t%s" % os.path.join(destroot,
                                                f.lstrip(os.path.sep)))
+                               msg.append("")
                                eerror(msg)
+
                        if not owners:
                                eerror(["None of the installed" + \
-                                       " packages claim the file(s)."])
+                                       " packages claim the file(s).", ""])
+
+                       # The explanation about the collision and how to solve
+                       # it may not be visible via a scrollback buffer, especially
+                       # if the number of file collisions is large. Therefore,
+                       # show a summary at the end.
+                       msg = ("Package '%s' NOT merged due to " + \
+                               "file collisions. If necessary, refer to your elog " + \
+                               "messages for the whole content of the above message.") % \
+                               self.settings.mycpv
+                       eerror(wrap(msg, 70))
+
                        if collision_protect:
                                return 1
 
index 66cd16244135944e4ec45ad173be528b53997403..ff34993a6cef092c1f77e4850229c3ab31531b2c 100644 (file)
@@ -74,6 +74,9 @@ class PortagePackageException(PortageException):
 class PackageNotFound(PortagePackageException):
        """Missing Ebuild or Binary"""
 
+class PackageSetNotFound(PortagePackageException):
+       """Missing package set"""
+
 class InvalidPackageName(PortagePackageException):
        """Malformed package name"""