aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'portage_with_autodep/pym/portage/locks.py')
-rw-r--r--portage_with_autodep/pym/portage/locks.py62
1 files changed, 51 insertions, 11 deletions
diff --git a/portage_with_autodep/pym/portage/locks.py b/portage_with_autodep/pym/portage/locks.py
index 59fbc6e..8571d8c 100644
--- a/portage_with_autodep/pym/portage/locks.py
+++ b/portage_with_autodep/pym/portage/locks.py
@@ -1,5 +1,5 @@
# portage: Lock management code
-# Copyright 2004-2012 Gentoo Foundation
+# Copyright 2004-2013 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2
__all__ = ["lockdir", "unlockdir", "lockfile", "unlockfile", \
@@ -17,7 +17,6 @@ import portage
from portage import os, _encodings, _unicode_decode
from portage.exception import DirectoryNotFound, FileNotFound, \
InvalidData, TryAgain, OperationNotPermitted, PermissionDenied
-from portage.data import portage_gid
from portage.util import writemsg
from portage.localization import _
@@ -64,6 +63,9 @@ def lockfile(mypath, wantnewlockfile=0, unlinkfile=0,
if not mypath:
raise InvalidData(_("Empty path given"))
+ # Since Python 3.4, chown requires int type (no proxies).
+ portage_gid = int(portage.data.portage_gid)
+
# Support for file object or integer file descriptor parameters is
# deprecated due to ambiguity in whether or not it's safe to close
# the file descriptor, making it prone to "Bad file descriptor" errors
@@ -148,7 +150,7 @@ def lockfile(mypath, wantnewlockfile=0, unlinkfile=0,
except IOError as e:
if not hasattr(e, "errno"):
raise
- if e.errno in (errno.EACCES, errno.EAGAIN):
+ if e.errno in (errno.EACCES, errno.EAGAIN, errno.ENOLCK):
# resource temp unavailable; eg, someone beat us to the lock.
if flags & os.O_NONBLOCK:
os.close(myfd)
@@ -163,19 +165,43 @@ def lockfile(mypath, wantnewlockfile=0, unlinkfile=0,
if isinstance(mypath, int):
waiting_msg = _("waiting for lock on fd %i") % myfd
else:
- waiting_msg = _("waiting for lock on %s\n") % lockfilename
+ waiting_msg = _("waiting for lock on %s") % lockfilename
if out is not None:
out.ebegin(waiting_msg)
# try for the exclusive lock now.
- try:
- locking_method(myfd, fcntl.LOCK_EX)
- except EnvironmentError as e:
- if out is not None:
- out.eend(1, str(e))
- raise
+ enolock_msg_shown = False
+ while True:
+ try:
+ locking_method(myfd, fcntl.LOCK_EX)
+ except EnvironmentError as e:
+ if e.errno == errno.ENOLCK:
+ # This is known to occur on Solaris NFS (see
+ # bug #462694). Assume that the error is due
+ # to temporary exhaustion of record locks,
+ # and loop until one becomes available.
+ if not enolock_msg_shown:
+ enolock_msg_shown = True
+ if isinstance(mypath, int):
+ context_desc = _("Error while waiting "
+ "to lock fd %i") % myfd
+ else:
+ context_desc = _("Error while waiting "
+ "to lock '%s'") % lockfilename
+ writemsg("\n!!! %s: %s\n" % (context_desc, e),
+ noiselevel=-1)
+
+ time.sleep(_HARDLINK_POLL_LATENCY)
+ continue
+
+ if out is not None:
+ out.eend(1, str(e))
+ raise
+ else:
+ break
+
if out is not None:
out.eend(os.EX_OK)
- elif e.errno in (errno.ENOSYS, errno.ENOLCK):
+ elif e.errno in (errno.ENOSYS,):
# We're not allowed to lock on this FS.
if not isinstance(lockfilename, int):
# If a file object was passed in, it's not safe
@@ -207,6 +233,17 @@ def lockfile(mypath, wantnewlockfile=0, unlinkfile=0,
waiting_msg=waiting_msg, flags=flags)
if myfd != HARDLINK_FD:
+
+ # FD_CLOEXEC is enabled by default in Python >=3.4.
+ if sys.hexversion < 0x3040000:
+ try:
+ fcntl.FD_CLOEXEC
+ except AttributeError:
+ pass
+ else:
+ fcntl.fcntl(myfd, fcntl.F_SETFD,
+ fcntl.fcntl(myfd, fcntl.F_GETFD) | fcntl.FD_CLOEXEC)
+
_open_fds.add(myfd)
writemsg(str((lockfilename,myfd,unlinkfile))+"\n",1)
@@ -339,6 +376,9 @@ def hardlink_lockfile(lockfilename, max_wait=DeprecationWarning,
preexisting = os.path.exists(lockfilename)
myhardlock = hardlock_name(lockfilename)
+ # Since Python 3.4, chown requires int type (no proxies).
+ portage_gid = int(portage.data.portage_gid)
+
# myhardlock must not exist prior to our link() call, and we can
# safely unlink it since its file name is unique to our PID
try: