From c3513c07ff90f0a71632c7caf935ab3cf2742a0a Mon Sep 17 00:00:00 2001 From: Fabian Groffen Date: Fri, 8 Dec 2006 08:01:42 +0000 Subject: [PATCH] Merged from trunk 5188:5196 Use a fake vartree for depgraph calculations. This minimizes the time that a lock needs to be held on the vardb, and allows in-memory global updates when necessary. Delete the depgraph when it's no longer needed. Use FakeVartree for vardb lock/cache during depclean. Allow depclean to silently skip packages unmerged behind it's back. Fix depclean so the fake vartree is used in dep_check calls. Always silently ingnore missing packages during unmerge. Remove all traces of the unmerge raise_on_missing parameter. Fix indentation. svn path=/main/branches/prefix/; revision=5223 --- bin/emerge | 67 ++++++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 52 insertions(+), 15 deletions(-) diff --git a/bin/emerge b/bin/emerge index 34f160333..a01a21d8e 100755 --- a/bin/emerge +++ b/bin/emerge @@ -700,6 +700,34 @@ class DepPriority(object): return "medium" return "soft" +class FakeVartree(object): + """This is implements an in-memory copy of a vartree instance that provides + all the interfaces required for use by the depgraph. The vardb is locked + during the constructor call just long enough to read a copy of the + installed package information. This allows the depgraph to do it's + dependency calculations without holding a lock on the vardb. It also + allows things like vardb global updates to be done in memory so that the + user doesn't necessarily need write access to the vardb in cases where + global updates are necessary (updates are performed when necessary if there + is not a matching ebuild in the tree).""" + def __init__(self, real_vartree): + self.root = real_vartree.root + self.settings = real_vartree.settings + self.dbapi = portage.fakedbapi(settings=real_vartree.settings) + vdb_path = os.path.join(self.root, portage.VDB_PATH) + vdb_lock = None + try: + if os.access(vdb_path, os.W_OK): + vdb_lock = portage_locks.lockdir(vdb_path) + mykeys = ["SLOT", "USE", "IUSE", "DEPEND", "RDEPEND", "PDEPEND"] + real_dbapi = real_vartree.dbapi + for cpv in real_dbapi.cpv_all(): + metadata = dict(zip(mykeys, real_dbapi.aux_get(cpv, mykeys))) + self.dbapi.cpv_inject(cpv, metadata=metadata) + finally: + if vdb_lock: + portage_locks.unlockdir(vdb_lock) + class depgraph: pkg_tree_map = { @@ -710,7 +738,6 @@ class depgraph: def __init__(self, settings, trees, myopts, myparams, spinner): self.settings = settings self.target_root = settings["ROOT"] - self.trees = trees self.myopts = myopts self.myparams = myparams self.edebug = 0 @@ -719,10 +746,17 @@ class depgraph: self.spinner = spinner self.pkgsettings = {} self.pkg_node_map = {} - for myroot in self.trees: + self.trees = {} + for myroot in trees: + self.trees[myroot] = {} + for tree in ("porttree", "bintree"): + self.trees[myroot][tree] = trees[myroot][tree] + self.trees[myroot]["vartree"] = \ + FakeVartree(trees[myroot]["vartree"]) self.pkgsettings[myroot] = portage.config( - clone=trees[myroot]["vartree"].settings) + clone=self.trees[myroot]["vartree"].settings) self.pkg_node_map[myroot] = {} + del trees self.useFlags = {} self.useFlags[self.target_root] = {} if self.target_root != "/": @@ -750,10 +784,10 @@ class depgraph: myslot = vardb.aux_get(pkg, ["SLOT"])[0] fakedb.cpv_inject(pkg, metadata={"SLOT":myslot}) if "--usepkg" in self.myopts: - trees["/"]["bintree"].populate( + self.trees["/"]["bintree"].populate( "--getbinpkg" in self.myopts, "--getbinpkgonly" in self.myopts) if self.target_root != "/": - trees[self.target_root]["bintree"].populate( + self.trees[self.target_root]["bintree"].populate( "--getbinpkg" in self.myopts, "--getbinpkgonly" in self.myopts) self.args_keys = [] @@ -2687,7 +2721,7 @@ class MergeTask(object): return os.EX_OK def unmerge(settings, myopts, vartree, unmerge_action, unmerge_files, - ldpath_mtimes, raise_on_missing=True): + ldpath_mtimes): candidate_catpkgs=[] global_unmerge=0 xterm_titles = "notitles" not in settings.features @@ -2827,12 +2861,9 @@ def unmerge(settings, myopts, vartree, unmerge_action, unmerge_files, #add a "=" if missing mymatch=localtree.dep_match("="+x) if not mymatch: - if raise_on_missing: - raise portage_exception.PackageNotFound(x) - else: - portage.writemsg("\n--- Couldn't find '%s' to %s.\n" % \ - (x, unmerge_action), noiselevel=-1) - continue + portage.writemsg("\n--- Couldn't find '%s' to %s.\n" % \ + (x, unmerge_action), noiselevel=-1) + continue mykey = portage.key_expand( portage.dep_getkey( mymatch[0]), mydb=vartree.dbapi, settings=settings) @@ -3896,7 +3927,9 @@ def action_depclean(settings, trees, ldpath_mtimes, xterm_titles = "notitles" not in settings.features portdb = trees[settings["ROOT"]]["porttree"].dbapi - vartree = trees[settings["ROOT"]]["vartree"] + real_vartree = trees[settings["ROOT"]]["vartree"] + vartree = FakeVartree(real_vartree) + trees[settings["ROOT"]]["vartree"] = vartree vardb = vartree.dbapi syslist = getlist(settings, "system") worldlist = getlist(settings, "world") @@ -3976,6 +4009,7 @@ def action_depclean(settings, trees, ldpath_mtimes, # Restore the portdb back to normal (see fake_vardb above). trees[settings["ROOT"]]["porttree"].dbapi = portdb + trees[settings["ROOT"]]["vartree"] = real_vartree if "--quiet" not in myopts: print "\b\b... done!\n" @@ -3997,7 +4031,8 @@ def action_depclean(settings, trees, ldpath_mtimes, cleanlist = [pkg for pkg in vardb.cpv_all() if not fakedb.cpv_exists(pkg)] if len(cleanlist): - unmerge(settings, myopts, vartree, "unmerge", cleanlist, ldpath_mtimes) + unmerge(settings, myopts, trees[settings["ROOT"]]["vartree"], + "unmerge", cleanlist, ldpath_mtimes) print "Packages installed: "+str(len(myvarlist)) print "Packages in world: "+str(len(worldlist)) @@ -4177,6 +4212,7 @@ def action_build(settings, trees, mtimedb, it to write the mtimedb""" mtimedb.filename = None time.sleep(3) # allow the parent to have first fetch + del mydepgraph retval = mergetask.merge( mtimedb["resume"]["mergelist"], favorites, mtimedb) if retval != os.EX_OK: @@ -4213,6 +4249,7 @@ def action_build(settings, trees, mtimedb, pkglist.append(pkg) else: pkglist = mydepgraph.altlist() + del mydepgraph mergetask = MergeTask(settings, trees, myopts) retval = mergetask.merge(pkglist, favorites, mtimedb) if retval != os.EX_OK: @@ -4721,7 +4758,7 @@ def emerge_main(): validate_ebuild_environment(trees) vartree = trees[settings["ROOT"]]["vartree"] if 1 == unmerge(settings, myopts, vartree, myaction, myfiles, - mtimedb["ldpath"], raise_on_missing=False): + mtimedb["ldpath"]): if "--pretend" not in myopts: post_emerge(settings, mtimedb, 0) -- 2.26.2