--- pym.orig/portage.py 2003-12-10 23:44:34.000000000 +0100 +++ pym/portage.py 2003-12-15 15:40:42.360865568 +0100 @@ -5820,57 +5820,77 @@ except OSError: pass -def flushmtimedb(record): - if mtimedb: - if record in mtimedb.keys(): - del mtimedb[record] +def flushmtimedb(record,myroot=root): + if myroot!=None and mtimedbdict.has_key(myroot): + if record in mytimedbdict[myroot].keys(): + del mytimedbdict[myroot][record] #print "mtimedb["+record+"] is cleared." else: writemsg("Invalid or unset record '"+record+"' in mtimedb.\n") + else: + writemsg("No mtimedb found for root "+myroot+"\n") #grab mtimes for eclasses and upgrades -mtimedb={} mtimedbkeys=[ "updates", "info", "version", "starttime", "resume" ] -mtimedbfile=root+"var/cache/edb/mtimedb" -try: - mypickle=cPickle.Unpickler(open(mtimedbfile)) - mypickle.find_global=None - mtimedb=mypickle.load() - if mtimedb.has_key("old"): - mtimedb["updates"]=mtimedb["old"] - del mtimedb["old"] - if mtimedb.has_key("cur"): - del mtimedb["cur"] -except: - #print "!!!",e - mtimedb={"updates":{},"version":"","starttime":0} - -for x in mtimedb.keys(): - if x not in mtimedbkeys: - writemsg("Deleting invalid mtimedb key: "+str(x)+"\n") - del mtimedb[x] +mtimedbdict={} +mtimedbdict[root]={} +if root!="/": + mtimedbdict["/"]={} +for mymtimedbroot in mtimedbdict.keys(): + mymtimedbfile=mymtimedbroot+"var/cache/edb/mtimedb" + try: + mypickle=cPickle.Unpickler(open(mymtimedbfile)) + mypickle.find_global=None + mtimedbdict[mymtimedbroot]=mypickle.load() + if mtimedbdict[mymtimedbroot].has_key("old"): + mtimedbdict[mymtimedbroot]["updates"]=mtimedbdict[mymtimedbroot]["old"] + del mtimedbdict[mymtimedbroot]["old"] + if mtimedbdict[mymtimedbroot].has_key("cur"): + del mtimedbdict[mymtimedbroot]["cur"] + except: + #print "!!!",e + mtimedbdict[mymtimedbroot]={"updates":{},"version":"","starttime":0} + + for x in mtimedbdict[mymtimedbroot].keys(): + if x not in mtimedbkeys: + writemsg("Deleting invalid "+str(mymtimedbroot)+" mtimedb key: "+str(x)+"\n") + del mtimedbdict[mymtimedbroot][x] + +# set portage.root mtimedb +# XXX BIG WARNING: this is only a reference, set for emerge compatibility... +# XXX I've checked this vars are never reaffected, and it should be okay. +# XXX But patching emerge would be safer. Sed does it very well: +# XXX sed -i 's:portage\.mtimedb:portage.mtimedbdict[portage.root]:' bin/emerge +mtimedb=mtimedbdict[root] #,"porttree":portagetree(root,virts),"bintree":binarytree(root,virts)} features=settings["FEATURES"].split() do_upgrade_packagesmessage=0 -def do_upgrade(mykey): +def do_upgrade(mykey,myroot="/"): global do_upgrade_packagesmessage writemsg("\n\n") writemsg(green("Performing Global Updates: ")+bold(mykey)+"\n") writemsg("(Could take a couple minutes if you have a lot of binary packages.)\n") - writemsg(" "+bold(".")+"='update pass' "+bold("*")+"='binary update' "+bold("@")+"='/var/db move'\n"+" "+bold("s")+"='/var/db SLOT move' "+bold("S")+"='binary SLOT move'\n") + # binaries updates are only for the "/" tree (no need to do them twice...) + # XXX Why is it that way though? Shouldn't bintree be populated + # XXX from root+settings["PKGDIR"] instead? Is it to have access + # XXX to other existing binaries, or something like this? + if myroot=="/": + writemsg(" "+bold(".")+"='update pass' "+bold("*")+"='binary update' "+bold("@")+"='/var/db move'\n"+" "+bold("s")+"='/var/db SLOT move' "+bold("S")+"='binary SLOT move'\n") + else: + writemsg(" "+bold(".")+"='update pass' "+bold("@")+"='"+myroot+"var/db move'"+" "+bold("s")+"='"+myroot+"var/db SLOT move'\n") processed=1 #remove stale virtual entries (mappings for packages that no longer exist) - myvirts=grabdict("/var/cache/edb/virtuals") + myvirts=grabdict(myroot+"var/cache/edb/virtuals") - worldlist=grabfile("/var/cache/edb/world") + worldlist=grabfile(myroot+"var/cache/edb/world") myupd=grabfile(mykey) - db["/"]["bintree"]=binarytree("/",settings["PKGDIR"],virts) + db[myroot]["bintree"]=binarytree(myroot,settings["PKGDIR"],virts) for myline in myupd: mysplit=myline.split() if not len(mysplit): @@ -5891,8 +5911,10 @@ sys.stdout.flush() if mysplit[0]=="move": - db["/"]["vartree"].dbapi.move_ent(mysplit) - db["/"]["bintree"].move_ent(mysplit) + db[myroot]["vartree"].dbapi.move_ent(mysplit) + # Do it only for "/" tree, since binaries are only there. + if myroot=="/": + db[myroot]["bintree"].move_ent(mysplit) #update world entries: for x in range(0,len(worldlist)): #update world entries, if any. @@ -5906,24 +5928,28 @@ myvirts[myvirt][mypos]=mysplit[2] elif mysplit[0]=="slotmove": - db["/"]["vartree"].dbapi.move_slot_ent(mysplit) - db["/"]["bintree"].move_slot_ent(mysplit,settings["PORTAGE_TMPDIR"]+"/tbz2") + db[myroot]["vartree"].dbapi.move_slot_ent(mysplit) + # Do it only for "/" tree, since binaries are only there. + if myroot=="/": + db[myroot]["bintree"].move_slot_ent(mysplit,settings["PORTAGE_TMPDIR"]+"/tbz2") # We gotta do the brute force updates for these now. - if (settings["PORTAGE_CALLER"] in ["fixpackages"]) or \ - ("fixpackages" in features): - db["/"]["bintree"].update_ents(myupd,settings["PORTAGE_TMPDIR"]+"/tbz2") - else: - do_upgrade_packagesmessage = 1 + # Do it only for "/" tree, since binaries are only there. + if myroot=="/": + if (settings["PORTAGE_CALLER"] in ["fixpackages"]) or \ + ("fixpackages" in features): + db[myroot]["bintree"].update_ents(myupd,settings["PORTAGE_TMPDIR"]+"/tbz2") + else: + do_upgrade_packagesmessage = 1 if processed: #update our internal mtime since we processed all our directives. - mtimedb["updates"][mykey]=os.stat(mykey)[ST_MTIME] - myworld=open("/var/cache/edb/world","w") + mtimedbdict[myroot]["updates"][mykey]=os.stat(mykey)[ST_MTIME] + myworld=open(myroot+"var/cache/edb/world","w") for x in worldlist: myworld.write(x+"\n") myworld.close() - writedict(myvirts,"/var/cache/edb/virtuals") + writedict(myvirts,myroot+"var/cache/edb/virtuals") print "" def portageexit(): @@ -5933,17 +5959,19 @@ for x in db.keys(): if db[x].has_key("porttree"): db[x]["porttree"].dbapi.save_auxcache(x) - if mtimedb: - # Store mtimedb - mymfn=mtimedbfile - try: - mtimedb["version"]=VERSION - cPickle.dump(mtimedb,open(mymfn,"w")) - #print "*** Wrote out mtimedb data successfully." - os.chown(mymfn,uid,portage_gid) - os.chmod(mymfn,0664) - except Exception, e: - pass + # both "/" and root mtimedbs should be saved + for mymtimedbroot in mtimedbdict.keys(): + if mtimedbdict[mymtimedbroot]: + # Store this mtimedb + mymfn=mymtimedbroot+"var/cache/edb/mtimedb" + try: + mtimedbdict[mymtimedbroot]["version"]=VERSION + cPickle.dump(mtimedbdict[mymtimedbroot],open(mymfn,"w")) + #print "*** Wrote out "+mymtimedbroot+" mtimedb data successfully." + os.chown(mymfn,uid,portage_gid) + os.chmod(mymfn,0664) + except Exception, e: + pass atexit.register(portageexit) @@ -5951,28 +5979,32 @@ if settings["PORTAGE_CALLER"] in ["emerge","fixpackages"]: #only do this if we're root and not running repoman/ebuild digest updpath=os.path.normpath(settings["PORTDIR"]+"///profiles/updates") - didupdate=0 - if not mtimedb.has_key("updates"): - mtimedb["updates"]={} try: mylist=listdir(updpath,EmptyOnError=1) # resort the list mylist=[myfile[3:]+"-"+myfile[:2] for myfile in mylist] mylist.sort() mylist=[myfile[5:]+"-"+myfile[:4] for myfile in mylist] + except OSError: + #directory doesn't exist + pass + # both "/" and "root" trees should be upgraded + didupdate=0 + for mymtimedbroot in mtimedbdict.keys(): + if not mtimedbdict[mymtimedbroot].has_key("updates"): + mtimedbdict[mymtimedbroot]["updates"]={} for myfile in mylist: mykey=updpath+"/"+myfile if not os.path.isfile(mykey): continue - if (not mtimedb["updates"].has_key(mykey)) or \ - (mtimedb["updates"][mykey] != os.stat(mykey)[ST_MTIME]) or \ + if (not mtimedbdict[mymtimedbroot]["updates"].has_key(mykey)) or \ + (mtimedbdict[mymtimedbroot]["updates"][mykey] != os.stat(mykey)[ST_MTIME]) or \ (settings["PORTAGE_CALLER"] == "fixpackages"): didupdate=1 - do_upgrade(mykey) + do_upgrade(mykey,myroot=mymtimedbroot) portageexit() # This lets us save state for C-c. - except OSError: - #directory doesn't exist - pass + # do_vartree can be done only once, it already takes care of both vartrees. + # And do_upgrade_packagesmessage is only about the "/" tree. if didupdate: #make sure our internal databases are consistent; recreate our virts and vartree do_vartree()