add _get_locker() method that reads and verifies pidfile.
make _lock, _unlock, _get_locker static methods.
---
 yum/__init__.py |   65 ++++++++++++++++++++++++++++++++----------------------
 1 files changed, 38 insertions(+), 27 deletions(-)

diff --git a/yum/__init__.py b/yum/__init__.py
index 1807d61..accd76d 100644
--- a/yum/__init__.py
+++ b/yum/__init__.py
@@ -1877,32 +1877,16 @@ class YumBase(depsolve.Depsolve):
         
         mypid=str(os.getpid())    
         while not self._lock(lockfile, mypid, 0644):
-            try:
-                fd = open(lockfile, 'r')
-            except (IOError, OSError), e:
-                msg = _("Could not open lock %s: %s") % (lockfile, e)
-                raise Errors.LockError(errno.EPERM, msg)
-                
-            try: oldpid = int(fd.readline())
-            except ValueError:
-                # bogus data in the pid file. Throw away.
+            oldpid = self._get_locker(lockfile)
+            if not oldpid:
+                # Invalid locker: unlink lockfile and retry
                 self._unlock(lockfile)
-            else:
-                if oldpid == os.getpid(): # if we own the lock, we're fine
-                    break
-                try: os.kill(oldpid, 0)
-                except OSError, e:
-                    if e[0] == errno.ESRCH:
-                        # The pid doesn't exist
-                        self._unlock(lockfile)
-                    else:
-                        # Whoa. What the heck happened?
-                        msg = _('Unable to check if PID %s is active') % oldpid
-                        raise Errors.LockError(errno.EPERM, msg, oldpid)
-                else:
-                    # Another copy seems to be running.
-                    msg = _('Existing lock %s: another copy is running as pid 
%s.') % (lockfile, oldpid)
-                    raise Errors.LockError(0, msg, oldpid)
+                continue
+            if oldpid == os.getpid(): # if we own the lock, we're fine
+                break
+            # Another copy seems to be running.
+            msg = _('Existing lock %s: another copy is running as pid %s.') % 
(lockfile, oldpid)
+            raise Errors.LockError(0, msg, oldpid)
         # We've got the lock, store it so we can auto-unlock on __del__...
         self._lockfile = lockfile
     
@@ -1937,7 +1921,8 @@ class YumBase(depsolve.Depsolve):
         self._unlock(lockfile)
         self._lockfile = None
         
-    def _lock(self, filename, contents='', mode=0777):
+    @staticmethod
+    def _lock(filename, contents='', mode=0777):
         lockdir = os.path.dirname(filename)
         try:
             if not os.path.exists(lockdir):
@@ -1953,9 +1938,35 @@ class YumBase(depsolve.Depsolve):
                 raise Errors.LockError(msg.errno, errmsg, int(contents))
             return 0
     
-    def _unlock(self, filename):
+    @staticmethod
+    def _unlock(filename):
         misc.unlink_f(filename)
 
+    @staticmethod
+    def _get_locker(lockfile):
+        try: fd = open(lockfile, 'r')
+        except (IOError, OSError), e:
+            msg = _("Could not open lock %s: %s") % (lockfile, e)
+            raise Errors.LockError(errno.EPERM, msg)
+        try: oldpid = int(fd.readline())
+        except ValueError:
+            return None # Bogus pid
+
+        try:
+            stat = open("/proc/%d/stat" % oldpid).readline()
+            if stat.split()[2] == 'Z':
+                return None # The pid is a zombie
+        except IOError:
+            # process dead or /proc not mounted
+            try: os.kill(oldpid, 0)
+            except OSError, e:
+                if e[0] == errno.ESRCH:
+                    return None # The pid doesn't exist
+                # Whoa. What the heck happened?
+                msg = _('Unable to check if PID %s is active') % oldpid
+                raise Errors.LockError(errno.EPERM, msg, oldpid)
+        return oldpid
+
     def verifyPkg(self, fo, po, raiseError):
         """Check that the checksum of a remote package matches what we
         expect it to be.  If the checksum of the package file is
-- 
1.7.4.4

_______________________________________________
Yum-devel mailing list
Yum-devel@lists.baseurl.org
http://lists.baseurl.org/mailman/listinfo/yum-devel

Reply via email to