From 44bf25fffa15970b7ab8677f718026e603ed2543 Mon Sep 17 00:00:00 2001
From: Iustin Pop <iustin@google.com>
Date: Tue, 11 Nov 2008 10:58:28 +0000
Subject: [PATCH] Remove zombie special case from IsProcessAlive

Based on the discussion on the mailing list, we remove the special
casing of zombie processes.

Note we don't use kill -0 since that has a different meaning than "check
process is alive", so this function is still linux-specific.

Reviewed-by: imsnah
---
 lib/utils.py                  | 22 ++++++----------------
 test/ganeti.utils_unittest.py | 26 --------------------------
 2 files changed, 6 insertions(+), 42 deletions(-)

diff --git a/lib/utils.py b/lib/utils.py
index 4de6a1e29..4c55dc9cf 100644
--- a/lib/utils.py
+++ b/lib/utils.py
@@ -352,8 +352,8 @@ def CheckDict(target, template, logname=None):
 def IsProcessAlive(pid):
   """Check if a given pid exists on the system.
 
-  @note: zombie processes treated as not alive, and giving a
-      pid M{<= 0} causes the function to return False.
+  @note: zombie status is not handled, so zombie processes
+      will be returned as alive
   @type pid: int
   @param pid: the process ID to check
   @rtype: boolean
@@ -364,22 +364,12 @@ def IsProcessAlive(pid):
     return False
 
   try:
-    f = open("/proc/%d/status" % pid)
-  except IOError, err:
+    os.stat("/proc/%d/status" % pid)
+    return True
+  except EnvironmentError, err:
     if err.errno in (errno.ENOENT, errno.ENOTDIR):
       return False
-
-  alive = True
-  try:
-    data = f.readlines()
-    if len(data) > 1:
-      state = data[1].split()
-      if len(state) > 1 and state[1] == "Z":
-        alive = False
-  finally:
-    f.close()
-
-  return alive
+    raise
 
 
 def ReadPidFile(pidfile):
diff --git a/test/ganeti.utils_unittest.py b/test/ganeti.utils_unittest.py
index ad6d44c64..d0dff6ef3 100755
--- a/test/ganeti.utils_unittest.py
+++ b/test/ganeti.utils_unittest.py
@@ -50,37 +50,11 @@ from ganeti.errors import LockError, UnitParseError, GenericError, \
 class TestIsProcessAlive(unittest.TestCase):
   """Testing case for IsProcessAlive"""
 
-  def _CreateZombie(self):
-    # create a zombie
-    r_fd, w_fd = os.pipe()
-    pid_zombie = os.fork()
-    if pid_zombie == 0:
-      # explicit close of read, write end will be closed only due to exit
-      os.close(r_fd)
-      os._exit(0)
-    elif pid_zombie < 0:
-      raise SystemError("can't fork")
-    # parent: we close our end of the w_fd, so reads will error as
-    # soon as the OS cleans the child's filedescriptors on its exit
-    os.close(w_fd)
-    # wait for 60 seconds at max for the exit (pathological case, just
-    # so that the test doesn't hang indefinitely)
-    r_set, w_set, e_set = select.select([r_fd], [], [], 60)
-    if not r_set and not e_set:
-      self.fail("Timeout exceeded in zombie creation")
-    return pid_zombie
-
   def testExists(self):
     mypid = os.getpid()
     self.assert_(IsProcessAlive(mypid),
                  "can't find myself running")
 
-  def testZombie(self):
-    pid_zombie = self._CreateZombie()
-    is_zombie = not IsProcessAlive(pid_zombie)
-    self.assert_(is_zombie, "zombie not detected as zombie")
-    os.waitpid(pid_zombie, os.WNOHANG)
-
   def testNotExisting(self):
     pid_non_existing = os.fork()
     if pid_non_existing == 0:
-- 
GitLab