Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(101)

Side by Side Diff: pym/portage/dbapi/vartree.py

Issue 6714030: Cleanup preserved lib locking in portage. (Closed)
Patch Set: Rebase Created 9 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « pym/_emerge/main.py ('k') | pym/portage/util/_dyn_libs/PreservedLibsRegistry.py » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 # Copyright 1998-2011 Gentoo Foundation 1 # Copyright 1998-2011 Gentoo Foundation
2 # Distributed under the terms of the GNU General Public License v2 2 # Distributed under the terms of the GNU General Public License v2
3 3
4 __all__ = [ 4 __all__ = [
5 "vardbapi", "vartree", "dblink"] + \ 5 "vardbapi", "vartree", "dblink"] + \
6 ["write_contents", "tar_contents"] 6 ["write_contents", "tar_contents"]
7 7
8 import portage 8 import portage
9 portage.proxy.lazyimport.lazyimport(globals(), 9 portage.proxy.lazyimport.lazyimport(globals(),
10 'portage.checksum:_perform_md5_merge@perform_md5', 10 'portage.checksum:_perform_md5_merge@perform_md5',
(...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after
141 "repository", "RESTRICT" , "SLOT", "USE", "DEFINED_PHASE S", 141 "repository", "RESTRICT" , "SLOT", "USE", "DEFINED_PHASE S",
142 "REQUIRED_USE"]) 142 "REQUIRED_USE"])
143 self._aux_cache_obj = None 143 self._aux_cache_obj = None
144 self._aux_cache_filename = os.path.join(self._eroot, 144 self._aux_cache_filename = os.path.join(self._eroot,
145 CACHE_PATH, "vdb_metadata.pickle") 145 CACHE_PATH, "vdb_metadata.pickle")
146 self._counter_path = os.path.join(self._eroot, 146 self._counter_path = os.path.join(self._eroot,
147 CACHE_PATH, "counter") 147 CACHE_PATH, "counter")
148 148
149 self._plib_registry = None 149 self._plib_registry = None
150 if _ENABLE_PRESERVE_LIBS: 150 if _ENABLE_PRESERVE_LIBS:
151 » » » try: 151 » » » self._plib_registry = PreservedLibsRegistry(self.root,
152 » » » » self._plib_registry = PreservedLibsRegistry(self .root, 152 » » » » os.path.join(self._eroot, PRIVATE_PATH,
153 » » » » » os.path.join(self._eroot, PRIVATE_PATH, 153 » » » » "preserved_libs_registry"))
154 » » » » » "preserved_libs_registry"))
155 » » » except PermissionDenied:
156 » » » » # apparently this user isn't allowed to access P RIVATE_PATH
157 » » » » pass
158 154
159 self._linkmap = None 155 self._linkmap = None
160 if _ENABLE_DYN_LINK_MAP: 156 if _ENABLE_DYN_LINK_MAP:
161 self._linkmap = LinkageMap(self) 157 self._linkmap = LinkageMap(self)
162 self._owners = self._owners_db(self) 158 self._owners = self._owners_db(self)
163 159
164 def getpath(self, mykey, filename=None): 160 def getpath(self, mykey, filename=None):
165 # This is an optimized hotspot, so don't use unicode-wrapped 161 # This is an optimized hotspot, so don't use unicode-wrapped
166 # os module and don't use os.path.join(). 162 # os module and don't use os.path.join().
167 rValue = self._eroot + VDB_PATH + _os.sep + mykey 163 rValue = self._eroot + VDB_PATH + _os.sep + mykey
(...skipping 1262 matching lines...) Expand 10 before | Expand all | Expand 10 after
1430 1426
1431 pkgfiles[path] = data 1427 pkgfiles[path] = data
1432 1428
1433 if errors: 1429 if errors:
1434 writemsg(_("!!! Parse error in '%s'\n") % contents_file, noiselevel=-1) 1430 writemsg(_("!!! Parse error in '%s'\n") % contents_file, noiselevel=-1)
1435 for pos, e in errors: 1431 for pos, e in errors:
1436 writemsg(_("!!! line %d: %s\n") % (pos, e), no iselevel=-1) 1432 writemsg(_("!!! line %d: %s\n") % (pos, e), no iselevel=-1)
1437 self.contentscache = pkgfiles 1433 self.contentscache = pkgfiles
1438 return pkgfiles 1434 return pkgfiles
1439 1435
1436 def _prune_plib_registry(self, others_in_slot=[]):
1437 # remove preserved libraries that don't have any consumers left
1438 plib_registry = self.vartree.dbapi._plib_registry
1439 if plib_registry:
1440 plib_registry.lock()
1441 try:
1442 plib_registry.load()
1443
1444 # Skip this if another package in the same slot has just been
1445 # merged on top of this package, since the other package has
1446 # already called LinkageMap.rebuild() and passed it's NEEDED file
1447 # in as an argument.
1448 if not others_in_slot:
1449 self._linkmap_rebuild(exclude_pkgs=(self .mycpv,))
1450
1451 cpv_lib_map = self._find_unused_preserved_libs()
1452 if cpv_lib_map:
1453 self._remove_preserved_libs(cpv_lib_map)
1454 for cpv, removed in cpv_lib_map.items():
1455 if not self.vartree.dbapi.cpv_ex ists(cpv):
1456 for dblnk in others_in_s lot:
1457 if dblnk.mycpv = = cpv:
1458 # This o ne just got merged so it doesn't
1459 # regist er with cpv_exists() yet.
1460 self.var tree.dbapi.removeFromContents(
1461 dblnk, removed)
1462 break
1463 continue
1464 self.vartree.dbapi.removeFromCon tents(cpv, removed)
1465 plib_registry.unregister(self.mycpv, self.settin gs["SLOT"],
1466 self.vartree.dbapi.cpv_counter(self.mycp v))
1467 plib_registry.store()
1468 finally:
1469 plib_registry.unlock()
1470
1440 def unmerge(self, pkgfiles=None, trimworld=None, cleanup=True, 1471 def unmerge(self, pkgfiles=None, trimworld=None, cleanup=True,
1441 ldpath_mtimes=None, others_in_slot=None): 1472 ldpath_mtimes=None, others_in_slot=None):
1442 """ 1473 """
1443 Calls prerm 1474 Calls prerm
1444 Unmerges a given package (CPV) 1475 Unmerges a given package (CPV)
1445 calls postrm 1476 calls postrm
1446 calls cleanrm 1477 calls cleanrm
1447 calls env_update 1478 calls env_update
1448 1479
1449 @param pkgfiles: files to unmerge (generally self.getcontents() ) 1480 @param pkgfiles: files to unmerge (generally self.getcontents() )
(...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after
1567 1598
1568 # XXX: Decide how to handle failures here. 1599 # XXX: Decide how to handle failures here.
1569 if retval != os.EX_OK: 1600 if retval != os.EX_OK:
1570 failures += 1 1601 failures += 1
1571 showMessage(_("!!! FAILED prerm: %s\n") % retval, 1602 showMessage(_("!!! FAILED prerm: %s\n") % retval,
1572 level=logging.ERROR, noiselevel= -1) 1603 level=logging.ERROR, noiselevel= -1)
1573 1604
1574 self._unmerge_pkgfiles(pkgfiles, others_in_slot) 1605 self._unmerge_pkgfiles(pkgfiles, others_in_slot)
1575 self._clear_contents_cache() 1606 self._clear_contents_cache()
1576 1607
1577 # Remove the registration of preserved libs for this pkg instance
1578 plib_registry = self.vartree.dbapi._plib_registry
1579 if plib_registry is None:
1580 # preserve-libs is entirely disabled
1581 pass
1582 else:
1583 plib_registry.unregister(self.mycpv, self.settin gs["SLOT"],
1584 self.vartree.dbapi.cpv_counter(self.mycp v))
1585
1586 if myebuildpath: 1608 if myebuildpath:
1587 ebuild_phase = "postrm" 1609 ebuild_phase = "postrm"
1588 phase = EbuildPhase(background=background, 1610 phase = EbuildPhase(background=background,
1589 phase=ebuild_phase, scheduler=scheduler, 1611 phase=ebuild_phase, scheduler=scheduler,
1590 settings=self.settings) 1612 settings=self.settings)
1591 phase.start() 1613 phase.start()
1592 retval = phase.wait() 1614 retval = phase.wait()
1593 1615
1594 # XXX: Decide how to handle failures here. 1616 # XXX: Decide how to handle failures here.
1595 if retval != os.EX_OK: 1617 if retval != os.EX_OK:
1596 failures += 1 1618 failures += 1
1597 showMessage(_("!!! FAILED postrm: %s\n") % retval, 1619 showMessage(_("!!! FAILED postrm: %s\n") % retval,
1598 level=logging.ERROR, noiselevel= -1) 1620 level=logging.ERROR, noiselevel= -1)
1599 1621
1600 » » » # Skip this if another package in the same slot has just been 1622 » » » self._prune_plib_registry(others_in_slot)
1601 » » » # merged on top of this package, since the other package has
1602 » » » # already called LinkageMap.rebuild() and passed it's NE EDED file
1603 » » » # in as an argument.
1604 » » » if not others_in_slot:
1605 » » » » self._linkmap_rebuild(exclude_pkgs=(self.mycpv,) )
1606
1607 » » » # remove preserved libraries that don't have any consume rs left
1608 » » » cpv_lib_map = self._find_unused_preserved_libs()
1609 » » » if cpv_lib_map:
1610 » » » » self._remove_preserved_libs(cpv_lib_map)
1611 » » » » for cpv, removed in cpv_lib_map.items():
1612 » » » » » if not self.vartree.dbapi.cpv_exists(cpv ):
1613 » » » » » » for dblnk in others_in_slot:
1614 » » » » » » » if dblnk.mycpv == cpv:
1615 » » » » » » » » # This one just got merged so it doesn't
1616 » » » » » » » » # register with cpv_exists() yet.
1617 » » » » » » » » self.vartree.dba pi.removeFromContents(
1618 » » » » » » » » » dblnk, r emoved)
1619 » » » » » » » » break
1620 » » » » » » continue
1621 » » » » » self.vartree.dbapi.removeFromContents(cp v, removed)
1622 » » » else:
1623 » » » » # Prune any preserved libs that may have
1624 » » » » # been unmerged with this package.
1625 » » » » if plib_registry is None:
1626 » » » » » # preserve-libs is entirely disabled
1627 » » » » » pass
1628 » » » » else:
1629 » » » » » plib_registry.pruneNonExisting()
1630
1631 finally: 1623 finally:
1632 self.vartree.dbapi._bump_mtime(self.mycpv) 1624 self.vartree.dbapi._bump_mtime(self.mycpv)
1633 if builddir_lock: 1625 if builddir_lock:
1634 try: 1626 try:
1635 if myebuildpath: 1627 if myebuildpath:
1636 if retval != os.EX_OK: 1628 if retval != os.EX_OK:
1637 msg_lines = [] 1629 msg_lines = []
1638 msg = _("The '%(ebuild_p hase)s' " 1630 msg = _("The '%(ebuild_p hase)s' "
1639 "phase of the '%(cpv)s' package " 1631 "phase of the '%(cpv)s' package "
1640 "has failed with exit va lue %(retval)s.") % \ 1632 "has failed with exit va lue %(retval)s.") % \
(...skipping 1687 matching lines...) Expand 10 before | Expand all | Expand 10 after
3328 showMessage(colorize("WARN", _("WARNING:")) 3320 showMessage(colorize("WARN", _("WARNING:"))
3329 + _(" AUTOCLEAN is disabled. This can cause ser ious" 3321 + _(" AUTOCLEAN is disabled. This can cause ser ious"
3330 " problems due to overlapping packages.\n"), 3322 " problems due to overlapping packages.\n"),
3331 level=logging.WARN, noiselevel=-1) 3323 level=logging.WARN, noiselevel=-1)
3332 3324
3333 # We hold both directory locks. 3325 # We hold both directory locks.
3334 self.dbdir = self.dbpkgdir 3326 self.dbdir = self.dbpkgdir
3335 self.delete() 3327 self.delete()
3336 _movefile(self.dbtmpdir, self.dbpkgdir, mysettings=self.settings ) 3328 _movefile(self.dbtmpdir, self.dbpkgdir, mysettings=self.settings )
3337 3329
3338 # keep track of the libs we preserved
3339 if self.vartree.dbapi._plib_registry is not None and \
3340 preserve_paths:
3341 self.vartree.dbapi._plib_registry.register(self.mycpv,
3342 slot, counter, sorted(preserve_paths))
3343
3344 # Check for file collisions with blocking packages 3330 # Check for file collisions with blocking packages
3345 # and remove any colliding files from their CONTENTS 3331 # and remove any colliding files from their CONTENTS
3346 # since they now belong to this package. 3332 # since they now belong to this package.
3347 self._clear_contents_cache() 3333 self._clear_contents_cache()
3348 contents = self.getcontents() 3334 contents = self.getcontents()
3349 destroot_len = len(destroot) - 1 3335 destroot_len = len(destroot) - 1
3350 for blocker in blockers: 3336 for blocker in blockers:
3351 self.vartree.dbapi.removeFromContents(blocker, iter(cont ents), 3337 self.vartree.dbapi.removeFromContents(blocker, iter(cont ents),
3352 relative_paths=False) 3338 relative_paths=False)
3353 3339
3354 # Unregister any preserved libs that this package has overwritte n
3355 # and update the contents of the packages that owned them.
3356 plib_registry = self.vartree.dbapi._plib_registry 3340 plib_registry = self.vartree.dbapi._plib_registry
3357 » » if plib_registry is None: 3341 » » if plib_registry:
3358 » » » # preserve-libs is entirely disabled 3342 » » » plib_registry.lock()
3359 » » » pass 3343 » » » try:
3360 » » else: 3344 » » » » plib_registry.load()
3361 » » » plib_dict = plib_registry.getPreservedLibs() 3345
3362 » » » for cpv, paths in plib_collisions.items(): 3346 » » » » if preserve_paths:
3363 » » » » if cpv not in plib_dict: 3347 » » » » » # keep track of the libs we preserved
3364 » » » » » continue 3348 » » » » » plib_registry.register(self.mycpv, slot, counter,
3365 » » » » if cpv == self.mycpv: 3349 » » » » » » sorted(preserve_paths))
3366 » » » » » continue 3350
3367 » » » » try: 3351 » » » » # Unregister any preserved libs that this packag e has overwritten
3368 » » » » » slot, counter = self.vartree.dbapi.aux_g et( 3352 » » » » # and update the contents of the packages that o wned them.
3369 » » » » » » cpv, ["SLOT", "COUNTER"]) 3353 » » » » plib_dict = plib_registry.getPreservedLibs()
3370 » » » » except KeyError: 3354 » » » » for cpv, paths in plib_collisions.items():
3371 » » » » » continue 3355 » » » » » if cpv not in plib_dict:
3372 » » » » remaining = [f for f in plib_dict[cpv] if f not in paths] 3356 » » » » » » continue
3373 » » » » plib_registry.register(cpv, slot, counter, remai ning) 3357 » » » » » if cpv == self.mycpv:
3374 » » » » self.vartree.dbapi.removeFromContents(cpv, paths ) 3358 » » » » » » continue
3359 » » » » » try:
3360 » » » » » » slot, counter = self.vartree.dba pi.aux_get(
3361 » » » » » » » cpv, ["SLOT", "COUNTER"] )
3362 » » » » » except KeyError:
3363 » » » » » » continue
3364 » » » » » remaining = [f for f in plib_dict[cpv] i f f not in paths]
3365 » » » » » plib_registry.register(cpv, slot, counte r, remaining)
3366 » » » » » self.vartree.dbapi.removeFromContents(cp v, paths)
3367
3368 » » » » plib_registry.store()
3369 » » » finally:
3370 » » » » plib_registry.unlock()
3375 3371
3376 self.vartree.dbapi._add(self) 3372 self.vartree.dbapi._add(self)
3377 contents = self.getcontents() 3373 contents = self.getcontents()
3378 3374
3379 #do postinst script 3375 #do postinst script
3380 self.settings["PORTAGE_UPDATE_ENV"] = \ 3376 self.settings["PORTAGE_UPDATE_ENV"] = \
3381 os.path.join(self.dbpkgdir, "environment.bz2") 3377 os.path.join(self.dbpkgdir, "environment.bz2")
3382 self.settings.backup_changes("PORTAGE_UPDATE_ENV") 3378 self.settings.backup_changes("PORTAGE_UPDATE_ENV")
3383 try: 3379 try:
3384 if scheduler is None: 3380 if scheduler is None:
(...skipping 18 matching lines...) Expand all
3403 downgrade = True 3399 downgrade = True
3404 3400
3405 #update environment settings, library paths. DO NOT change symli nks. 3401 #update environment settings, library paths. DO NOT change symli nks.
3406 env_update(makelinks=(not downgrade), 3402 env_update(makelinks=(not downgrade),
3407 target_root=self.settings['ROOT'], prev_mtimes=prev_mtim es, 3403 target_root=self.settings['ROOT'], prev_mtimes=prev_mtim es,
3408 contents=contents, env=self.settings.environ(), 3404 contents=contents, env=self.settings.environ(),
3409 writemsg_level=self._display_merge) 3405 writemsg_level=self._display_merge)
3410 3406
3411 # For gcc upgrades, preserved libs have to be removed after the 3407 # For gcc upgrades, preserved libs have to be removed after the
3412 # the library path has been updated. 3408 # the library path has been updated.
3413 » » self._linkmap_rebuild() 3409 » » self._prune_plib_registry()
3414 » » cpv_lib_map = self._find_unused_preserved_libs()
3415 » » if cpv_lib_map:
3416 » » » self._remove_preserved_libs(cpv_lib_map)
3417 » » » for cpv, removed in cpv_lib_map.items():
3418 » » » » if not self.vartree.dbapi.cpv_exists(cpv):
3419 » » » » » continue
3420 » » » » self.vartree.dbapi.removeFromContents(cpv, remov ed)
3421 3410
3422 return os.EX_OK 3411 return os.EX_OK
3423 3412
3424 def _new_backup_path(self, p): 3413 def _new_backup_path(self, p):
3425 """ 3414 """
3426 The works for any type path, such as a regular file, symlink, 3415 The works for any type path, such as a regular file, symlink,
3427 or directory. The parent directory is assumed to exist. 3416 or directory. The parent directory is assumed to exist.
3428 The returned filename is of the form p + '.backup.' + x, where 3417 The returned filename is of the form p + '.backup.' + x, where
3429 x guarantees that the returned path does not exist yet. 3418 x guarantees that the returned path does not exist yet.
3430 """ 3419 """
(...skipping 401 matching lines...) Expand 10 before | Expand all | Expand 10 after
3832 def merge(self, mergeroot, inforoot, myroot=None, myebuild=None, cleanup =0, 3821 def merge(self, mergeroot, inforoot, myroot=None, myebuild=None, cleanup =0,
3833 mydbapi=None, prev_mtimes=None): 3822 mydbapi=None, prev_mtimes=None):
3834 """ 3823 """
3835 @param myroot: ignored, self._eroot is used instead 3824 @param myroot: ignored, self._eroot is used instead
3836 """ 3825 """
3837 myroot = None 3826 myroot = None
3838 retval = -1 3827 retval = -1
3839 self.lockdb() 3828 self.lockdb()
3840 self.vartree.dbapi._bump_mtime(self.mycpv) 3829 self.vartree.dbapi._bump_mtime(self.mycpv)
3841 try: 3830 try:
3842 plib_registry = self.vartree.dbapi._plib_registry
3843 if plib_registry is None:
3844 # preserve-libs is entirely disabled
3845 pass
3846 else:
3847 plib_registry.load()
3848 plib_registry.pruneNonExisting()
3849
3850 retval = self.treewalk(mergeroot, myroot, inforoot, myeb uild, 3831 retval = self.treewalk(mergeroot, myroot, inforoot, myeb uild,
3851 cleanup=cleanup, mydbapi=mydbapi, prev_mtimes=pr ev_mtimes) 3832 cleanup=cleanup, mydbapi=mydbapi, prev_mtimes=pr ev_mtimes)
3852 3833
3853 # If PORTAGE_BUILDDIR doesn't exist, then it probably me ans 3834 # If PORTAGE_BUILDDIR doesn't exist, then it probably me ans
3854 # fail-clean is enabled, and the success/die hooks have 3835 # fail-clean is enabled, and the success/die hooks have
3855 # already been called by _emerge.EbuildPhase (via 3836 # already been called by _emerge.EbuildPhase (via
3856 # self._scheduler.dblinkEbuildPhase) prior to cleaning. 3837 # self._scheduler.dblinkEbuildPhase) prior to cleaning.
3857 if os.path.isdir(self.settings['PORTAGE_BUILDDIR']): 3838 if os.path.isdir(self.settings['PORTAGE_BUILDDIR']):
3858 3839
3859 if retval == os.EX_OK: 3840 if retval == os.EX_OK:
(...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after
3994 """ 3975 """
3995 myroot = None 3976 myroot = None
3996 if settings is None: 3977 if settings is None:
3997 raise TypeError("settings argument is required") 3978 raise TypeError("settings argument is required")
3998 mylink = dblink(cat, pkg, settings=settings, treetype="vartree", 3979 mylink = dblink(cat, pkg, settings=settings, treetype="vartree",
3999 vartree=vartree, scheduler=scheduler) 3980 vartree=vartree, scheduler=scheduler)
4000 vartree = mylink.vartree 3981 vartree = mylink.vartree
4001 try: 3982 try:
4002 mylink.lockdb() 3983 mylink.lockdb()
4003 if mylink.exists(): 3984 if mylink.exists():
4004 plib_registry = vartree.dbapi._plib_registry
4005 if plib_registry is None:
4006 # preserve-libs is entirely disabled
4007 pass
4008 else:
4009 plib_registry.load()
4010 plib_registry.pruneNonExisting()
4011 retval = mylink.unmerge(ldpath_mtimes=ldpath_mtimes) 3985 retval = mylink.unmerge(ldpath_mtimes=ldpath_mtimes)
4012 if retval == os.EX_OK: 3986 if retval == os.EX_OK:
4013 mylink.delete() 3987 mylink.delete()
4014 return retval 3988 return retval
4015 return os.EX_OK 3989 return os.EX_OK
4016 finally: 3990 finally:
4017 if vartree.dbapi._linkmap is None: 3991 if vartree.dbapi._linkmap is None:
4018 # preserve-libs is entirely disabled 3992 # preserve-libs is entirely disabled
4019 pass 3993 pass
4020 else: 3994 else:
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after
4117 encoding=object.__getattribute__(os, '_e ncoding'), 4091 encoding=object.__getattribute__(os, '_e ncoding'),
4118 errors='strict'), 'rb') 4092 errors='strict'), 'rb')
4119 try: 4093 try:
4120 tar.addfile(tarinfo, f) 4094 tar.addfile(tarinfo, f)
4121 finally: 4095 finally:
4122 f.close() 4096 f.close()
4123 else: 4097 else:
4124 tar.addfile(tarinfo) 4098 tar.addfile(tarinfo)
4125 if onProgress: 4099 if onProgress:
4126 onProgress(maxval, curval) 4100 onProgress(maxval, curval)
OLDNEW
« no previous file with comments | « pym/_emerge/main.py ('k') | pym/portage/util/_dyn_libs/PreservedLibsRegistry.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698