Bug #212882
authorZac Medico <zmedico@gentoo.org>
Thu, 27 Mar 2008 04:50:32 +0000 (04:50 -0000)
committerZac Medico <zmedico@gentoo.org>
Thu, 27 Mar 2008 04:50:32 +0000 (04:50 -0000)
- For compatibility with ENOENT exceptions raised from
fstat calls with CIFS, wrap fstat calls with an appropriate exception
handler. (trunk r9474)

- Fix lockfile() to handle errno.EACCES raised from the fcntl
call since the spec says that it's equivalent to EAGAIN and it appears that
CIFS returns EACCES in this case. (trunk r9458)

svn path=/main/branches/2.1.2/; revision=9518

pym/portage_locks.py

index 9b17c60e3c96c2cb16e1a66b57696e8c7c9fffe4..340096a7cc5f5427abbe1b6b091f3bd5f7226f01 100644 (file)
@@ -79,7 +79,7 @@ def lockfile(mypath, wantnewlockfile=0, unlinkfile=0, waiting_msg=None):
        except IOError, e:
                if "errno" not in dir(e):
                        raise
-               if e.errno == errno.EAGAIN:
+               if e.errno in (errno.EACCES, errno.EAGAIN):
                        # resource temp unavailable; eg, someone beat us to the lock.
                        if waiting_msg is None:
                                if isinstance(mypath, int):
@@ -111,7 +111,7 @@ def lockfile(mypath, wantnewlockfile=0, unlinkfile=0, waiting_msg=None):
 
                
        if type(lockfilename) == types.StringType and \
-               myfd != HARDLINK_FD and os.fstat(myfd).st_nlink == 0:
+               myfd != HARDLINK_FD and _fstat_nlink(myfd) == 0:
                # The file was deleted on us... Keep trying to make one...
                os.close(myfd)
                portage_util.writemsg("lockfile recurse\n",1)
@@ -122,6 +122,22 @@ def lockfile(mypath, wantnewlockfile=0, unlinkfile=0, waiting_msg=None):
        portage_util.writemsg(str((lockfilename,myfd,unlinkfile))+"\n",1)
        return (lockfilename,myfd,unlinkfile,locking_method)
 
+def _fstat_nlink(fd):
+       """
+       @param fd: an open file descriptor
+       @type fd: Integer
+       @rtype: Integer
+       @return: the current number of hardlinks to the file
+       """
+       try:
+               return os.fstat(fd).st_nlink
+       except EnvironmentError, e:
+               if e.errno == errno.ENOENT:
+                       # Some filesystems such as CIFS return
+                       # ENOENT which means st_nlink == 0.
+                       return 0
+               raise
+
 def unlockfile(mytuple):
        import fcntl
 
@@ -167,7 +183,7 @@ def unlockfile(mytuple):
                        # We won the lock, so there isn't competition for it.
                        # We can safely delete the file.
                        portage_util.writemsg("Got the lockfile...\n",1)
-                       if os.fstat(myfd).st_nlink == 1:
+                       if _fstat_nlink(myfd) == 1:
                                os.unlink(lockfilename)
                                portage_util.writemsg("Unlinked lockfile...\n",1)
                                locking_method(myfd,fcntl.LOCK_UN)