Revision 560cbec1

b/daemons/import-export
459 459

  
460 460
    """
461 461
    logging.info("Sending signal %s to child process", signum)
462
    os.killpg(self.pid, signum)
462
    utils.IgnoreProcessNotFound(os.killpg, self.pid, signum)
463 463

  
464 464
  def ForceQuit(self):
465 465
    """Ensure child process is no longer running.
b/lib/backend.py
2764 2764
  if pid:
2765 2765
    logging.info("Import/export %s is running with PID %s, sending SIGTERM",
2766 2766
                 name, pid)
2767
    os.kill(pid, signal.SIGTERM)
2767
    utils.IgnoreProcessNotFound(os.kill, pid, signal.SIGTERM)
2768 2768

  
2769 2769

  
2770 2770
def CleanupImportExport(name):
b/lib/impexpd/__init__.py
344 344
        raise
345 345

  
346 346
      # Process no longer exists
347
      logging.debug("dd exited")
347 348
      self._dd_pid = None
348 349

  
349 350
    return True
b/lib/utils.py
2342 2342
  """
2343 2343
  def _helper(pid, signal_, wait):
2344 2344
    """Simple helper to encapsulate the kill/waitpid sequence"""
2345
    os.kill(pid, signal_)
2346
    if wait:
2345
    if IgnoreProcessNotFound(os.kill, pid, signal_) and wait:
2347 2346
      try:
2348 2347
        os.waitpid(pid, os.WNOHANG)
2349 2348
      except OSError:
......
3122 3121
  return bool(exitcode)
3123 3122

  
3124 3123

  
3124
def IgnoreProcessNotFound(fn, *args, **kwargs):
3125
  """Ignores ESRCH when calling a process-related function.
3126

  
3127
  ESRCH is raised when a process is not found.
3128

  
3129
  @rtype: bool
3130
  @return: Whether process was found
3131

  
3132
  """
3133
  try:
3134
    fn(*args, **kwargs)
3135
  except EnvironmentError, err:
3136
    # Ignore ESRCH
3137
    if err.errno == errno.ESRCH:
3138
      return False
3139
    raise
3140

  
3141
  return True
3142

  
3143

  
3125 3144
def IgnoreSignals(fn, *args, **kwargs):
3126 3145
  """Tries to call a function ignoring failures due to EINTR.
3127 3146

  
b/test/ganeti.utils_unittest.py
2393 2393
    self.assertEqual(utils.FormatSeconds(3912.8), "1h 5m 13s")
2394 2394

  
2395 2395

  
2396
class RunIgnoreProcessNotFound(unittest.TestCase):
2397
  @staticmethod
2398
  def _WritePid(fd):
2399
    os.write(fd, str(os.getpid()))
2400
    os.close(fd)
2401
    return True
2402

  
2403
  def test(self):
2404
    (pid_read_fd, pid_write_fd) = os.pipe()
2405

  
2406
    # Start short-lived process which writes its PID to pipe
2407
    self.assert_(utils.RunInSeparateProcess(self._WritePid, pid_write_fd))
2408
    os.close(pid_write_fd)
2409

  
2410
    # Read PID from pipe
2411
    pid = int(os.read(pid_read_fd, 1024))
2412
    os.close(pid_read_fd)
2413

  
2414
    # Try to send signal to process which exited recently
2415
    self.assertFalse(utils.IgnoreProcessNotFound(os.kill, pid, 0))
2416

  
2417

  
2396 2418
if __name__ == '__main__':
2397 2419
  testutils.GanetiTestProgram()

Also available in: Unified diff