summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorZac Medico <zmedico@gentoo.org>2010-05-13 16:39:22 -0700
committerZac Medico <zmedico@gentoo.org>2010-05-13 16:39:22 -0700
commite9702f17c6ac1f185cf58b45d7bba1b2df51a8b7 (patch)
treecb10d8dd2b369dbcb2afc2a2a0e3f3a7d2c39321
parentDefine __all__. (diff)
downloadportage-idfetch-e9702f17c6ac1f185cf58b45d7bba1b2df51a8b7.tar.gz
portage-idfetch-e9702f17c6ac1f185cf58b45d7bba1b2df51a8b7.tar.bz2
portage-idfetch-e9702f17c6ac1f185cf58b45d7bba1b2df51a8b7.zip
Add a break_hardlinks parameter for tbz2 recompose methods, and enable it
by default. Since bindbapi.aux_update() calls this method, this changes the default behavior for all modifications to binary package metadata. This makes it safe to use hardlinks to create cheap snapshots of the repository, which is useful for solving race conditions on binhosts as described here: http://code.google.com/p/chromium-os/issues/detail?id=3225.
-rw-r--r--pym/portage/xpak.py29
1 files changed, 26 insertions, 3 deletions
diff --git a/pym/portage/xpak.py b/pym/portage/xpak.py
index 36aad39f..7487d672 100644
--- a/pym/portage/xpak.py
+++ b/pym/portage/xpak.py
@@ -25,6 +25,7 @@ import errno
import shutil
import sys
+import portage
from portage import os
from portage import normalize_path
from portage import _encodings
@@ -295,17 +296,39 @@ class tbz2(object):
def compose(self,datadir,cleanup=0):
"""Alias for recompose()."""
return self.recompose(datadir,cleanup)
- def recompose(self,datadir,cleanup=0):
+
+ def recompose(self, datadir, cleanup=0, break_hardlinks=True):
"""Creates an xpak segment from the datadir provided, truncates the tbz2
to the end of regular data if an xpak segment already exists, and adds
the new segment to the file with terminating info."""
xpdata = xpak(datadir)
- self.recompose_mem(xpdata)
+ self.recompose_mem(xpdata, break_hardlinks=break_hardlinks)
if cleanup:
self.cleanup(datadir)
- def recompose_mem(self, xpdata):
+ def recompose_mem(self, xpdata, break_hardlinks=True):
+ """
+ Update the xpak segment.
+ @param xpdata: A new xpak segment to be written, like that returned
+ from the xpak_mem() function.
+ @param break_hardlinks: If hardlinks exist, create a copy in order
+ to break them. This makes it safe to use hardlinks to create
+ cheap snapshots of the repository, which is useful for solving
+ race conditions on binhosts as described here:
+ http://code.google.com/p/chromium-os/issues/detail?id=3225.
+ Default is True.
+ """
self.scan() # Don't care about condition... We'll rewrite the data anyway.
+
+ if break_hardlinks and self.filestat.st_nlink > 1:
+ tmp_fname = "%s.%d" % (self.file, os.getpid())
+ shutil.copyfile(self.file, tmp_fname)
+ try:
+ portage.util.apply_stat_permissions(self.file, self.filestat)
+ except portage.exception.OperationNotPermitted:
+ pass
+ os.rename(tmp_fname, self.file)
+
myfile = open(_unicode_encode(self.file,
encoding=_encodings['fs'], errors='strict'), 'ab+')
if not myfile: