Revision d9f311d7

b/lib/utils.py
268 268

  
269 269
  Returns: true or false, depending on if the pid exists or not
270 270

  
271
  Remarks: zombie processes treated as not alive
271
  Remarks: zombie processes treated as not alive, and giving a pid <=
272
  0 makes the function to return False.
272 273

  
273 274
  """
275
  if pid <= 0:
276
    return False
277

  
274 278
  try:
275 279
    f = open("/proc/%d/status" % pid)
276 280
  except IOError, err:
......
290 294
  return alive
291 295

  
292 296

  
293
def IsPidFileAlive(pidfile):
294
  """Check whether the given pidfile points to a live process.
297
def ReadPidFile(pidfile):
298
  """Read the pid from a file.
295 299

  
296
    @param pidfile: Path to a file containing the pid to be checked
297
    @type  pidfile: string (filename)
300
  @param pidfile: Path to a file containing the pid to be checked
301
  @type  pidfile: string (filename)
302
  @return: The process id, if the file exista and contains a valid PID,
303
           otherwise 0
304
  @rtype: int
298 305

  
299 306
  """
300 307
  try:
301 308
    pf = open(pidfile, 'r')
302
  except EnvironmentError, open_err:
303
    if open_err.errno == errno.ENOENT:
304
      return False
305
    else:
306
      raise errors.GenericError("Cannot open file %s. Error: %s" %
307
                                (pidfile, str(open_err)))
309
  except EnvironmentError, err:
310
    if err.errno != errno.ENOENT:
311
      logging.exception("Can't read pid file?!")
312
    return 0
308 313

  
309 314
  try:
310 315
    pid = int(pf.read())
311
  except ValueError:
312
    raise errors.GenericError("Invalid pid string in %s" %
313
                              (pidfile,))
316
  except ValueError, err:
317
    logging.info("Can't parse pid file contents", exc_info=err)
318
    return 0
314 319

  
315
  return IsProcessAlive(pid)
320
  return pid
316 321

  
317 322

  
318 323
def MatchNameComponent(key, name_list):
......
1066 1071
  """
1067 1072
  pid = os.getpid()
1068 1073
  pidfilename = _DaemonPidFileName(name)
1069
  if IsPidFileAlive(pidfilename):
1074
  if IsProcessAlive(ReadPidFile(pidfilename)):
1070 1075
    raise errors.GenericError("%s contains a live process" % pidfilename)
1071 1076

  
1072 1077
  WriteFile(pidfilename, data="%d\n" % pid)
b/test/ganeti.utils_unittest.py
43 43
     ParseUnit, AddAuthorizedKey, RemoveAuthorizedKey, \
44 44
     ShellQuote, ShellQuoteArgs, TcpPing, ListVisibleFiles, \
45 45
     SetEtcHostsEntry, RemoveEtcHostsEntry, FirstFree
46
from ganeti.errors import LockError, UnitParseError
46
from ganeti.errors import LockError, UnitParseError, GenericError
47 47

  
48 48
def _ChildHandler(signal, stack):
49 49
  global _ChildFlag
50 50
  _ChildFlag = True
51 51

  
52

  
52 53
class TestIsProcessAlive(unittest.TestCase):
53 54
  """Testing case for IsProcessAlive"""
54 55

  
......
99 100
    self.assert_(not IsProcessAlive(self.pid_non_existing),
100 101
                 "noexisting process detected")
101 102

  
103

  
102 104
class TestPidFileFunctions(unittest.TestCase):
103
  """Tests for WritePidFile, RemovePidFile and IsPidFileAlive"""
105
  """Tests for WritePidFile, RemovePidFile and ReadPidFile"""
104 106

  
105 107
  def setUp(self):
106 108
    self.dir = tempfile.mkdtemp()
......
108 110
    utils._DaemonPidFileName = self.f_dpn
109 111

  
110 112
  def testPidFileFunctions(self):
113
    pid_file = self.f_dpn('test')
111 114
    utils.WritePidFile('test')
112
    self.assert_(os.path.exists(self.f_dpn('test')))
113
    self.assert_(utils.IsPidFileAlive(self.f_dpn('test')))
115
    self.failUnless(os.path.exists(pid_file),
116
                    "PID file should have been created")
117
    read_pid = utils.ReadPidFile(pid_file)
118
    self.failUnlessEqual(read_pid, os.getpid())
119
    self.failUnless(utils.IsProcessAlive(read_pid))
120
    self.failUnlessRaises(GenericError, utils.WritePidFile, 'test')
121
    utils.RemovePidFile('test')
122
    self.failIf(os.path.exists(pid_file),
123
                "PID file should not exist anymore")
124
    self.failUnlessEqual(utils.ReadPidFile(pid_file), 0,
125
                         "ReadPidFile should return 0 for missing pid file")
126
    fh = open(pid_file, "w")
127
    fh.write("blah\n")
128
    fh.close()
129
    self.failUnlessEqual(utils.ReadPidFile(pid_file), 0,
130
                         "ReadPidFile should return 0 for invalid pid file")
114 131
    utils.RemovePidFile('test')
115
    self.assert_(not os.path.exists(self.f_dpn('test')))
132
    self.failIf(os.path.exists(pid_file),
133
                "PID file should not exist anymore")
116 134

  
117 135
  def tearDown(self):
136
    for name in os.listdir(self.dir):
137
      os.unlink(os.path.join(self.dir, name))
118 138
    os.rmdir(self.dir)
119 139

  
120 140

  

Also available in: Unified diff