summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--pym/portage/dbapi/vartree.py61
1 files changed, 37 insertions, 24 deletions
diff --git a/pym/portage/dbapi/vartree.py b/pym/portage/dbapi/vartree.py
index 15c2586ea..efaee6ede 100644
--- a/pym/portage/dbapi/vartree.py
+++ b/pym/portage/dbapi/vartree.py
@@ -199,6 +199,8 @@ class vardbapi(dbapi):
self._aux_cache_version = "1"
self._aux_cache_filename = os.path.join(self.root,
CACHE_PATH.lstrip(os.path.sep), "vdb_metadata.pickle")
+ self._counter_path = os.path.join(root,
+ CACHE_PATH.lstrip(os.path.sep), "counter")
self.libmap = LibraryPackageMap(os.path.join(self.root, CACHE_PATH.lstrip(os.sep), "library_consumers"), self)
try:
@@ -609,6 +611,13 @@ class vardbapi(dbapi):
calls should only take a short time, so performance
is sufficient without having to rely on a potentially
corrupt global counter file.
+
+ The global counter file located at
+ $CACHE_PATH/counter serves to record the
+ counter of the last installed package and
+ it also corresponds to the total number of
+ installation actions that have occurred in
+ the history of this package database.
"""
cp_list = self.cp_list
max_counter = 0
@@ -620,48 +629,52 @@ class vardbapi(dbapi):
continue
if counter > max_counter:
max_counter = counter
- return max_counter + 1
- def counter_tick_core(self, myroot, incrementing=1, mycpv=None):
- "This method will grab the next COUNTER value and record it back to the global file. Returns new counter value."
- cpath = os.path.join(myroot, CACHE_PATH.lstrip(os.sep), "counter")
- changed = False
counter = -1
try:
- cfile = open(cpath, "r")
- except EnvironmentError:
- writemsg("!!! COUNTER file is missing: '%s'\n" % cpath,
- noiselevel=-1)
+ cfile = open(self._counter_path, "r")
+ except EnvironmentError, e:
+ writemsg("!!! Unable to read COUNTER file: '%s'\n" % \
+ self._counter_path, noiselevel=-1)
+ writemsg("!!! %s\n" % str(e), noiselevel=-1)
+ del e
else:
try:
try:
counter = long(cfile.readline().strip())
finally:
cfile.close()
- except (OverflowError, ValueError):
- writemsg("!!! COUNTER file is corrupt: '%s'\n" % cpath,
- noiselevel=-1)
+ except (OverflowError, ValueError), e:
+ writemsg("!!! COUNTER file is corrupt: '%s'\n" % \
+ self._counter_path, noiselevel=-1)
+ writemsg("!!! %s\n" % str(e), noiselevel=-1)
+ del e
- real_counter = self.get_counter_tick_core(myroot, mycpv=mycpv) - 1
+ # We must ensure that we return a counter
+ # value that is at least as large as the
+ # highest one from the installed packages,
+ # since having a corrupt value that is too low
+ # can trigger incorrect AUTOCLEAN behavior due
+ # to newly installed packages having lower
+ # COUNTERs than the previous version in the
+ # same slot.
+ if counter > max_counter:
+ max_counter = counter
if counter < 0:
- changed = True
writemsg("!!! Initializing COUNTER to " + \
- "value of %d\n" % counter, noiselevel=-1)
+ "value of %d\n" % max_counter, noiselevel=-1)
- # Never trust the counter file, since having a
- # corrupt value that is too low there can trigger
- # incorrect AUTOCLEAN behavior due to newly installed
- # packages having lower counters than the previous
- # version in the same slot.
- counter = real_counter
-
- if incrementing or changed:
+ return max_counter + 1
+ def counter_tick_core(self, myroot, incrementing=1, mycpv=None):
+ "This method will grab the next COUNTER value and record it back to the global file. Returns new counter value."
+ counter = self.get_counter_tick_core(myroot, mycpv=mycpv) - 1
+ if incrementing:
#increment counter
counter += 1
# update new global counter file
- write_atomic(cpath, str(counter))
+ write_atomic(self._counter_path, str(counter))
return counter
class vartree(object):