Revision debed9ae

b/lib/backend.py
2855 2855
  logging.info("Finalizing import/export %s", name)
2856 2856

  
2857 2857
  status_dir = utils.PathJoin(constants.IMPORT_EXPORT_DIR, name)
2858
  pid_file = utils.PathJoin(status_dir, _IES_PID_FILE)
2859 2858

  
2860
  pid = None
2861
  try:
2862
    fd = os.open(pid_file, os.O_RDONLY)
2863
  except EnvironmentError, err:
2864
    if err.errno != errno.ENOENT:
2865
      raise
2866
    # PID file doesn't exist
2867
  else:
2868
    try:
2869
      try:
2870
        # Try to acquire lock
2871
        utils.LockFile(fd)
2872
      except errors.LockError:
2873
        # Couldn't lock, daemon is running
2874
        pid = int(os.read(fd, 100))
2875
    finally:
2876
      os.close(fd)
2859
  pid = utils.ReadLockedPidFile(utils.PathJoin(status_dir, _IES_PID_FILE))
2877 2860

  
2878 2861
  if pid:
2879 2862
    logging.info("Import/export %s is still running with PID %s",
b/lib/utils.py
840 840
  return pid
841 841

  
842 842

  
843
def ReadLockedPidFile(path):
844
  """Reads a locked PID file.
845

  
846
  This can be used together with L{StartDaemon}.
847

  
848
  @type path: string
849
  @param path: Path to PID file
850
  @return: PID as integer or, if file was unlocked or couldn't be opened, None
851

  
852
  """
853
  try:
854
    fd = os.open(path, os.O_RDONLY)
855
  except EnvironmentError, err:
856
    if err.errno == errno.ENOENT:
857
      # PID file doesn't exist
858
      return None
859
    raise
860

  
861
  try:
862
    try:
863
      # Try to acquire lock
864
      LockFile(fd)
865
    except errors.LockError:
866
      # Couldn't lock, daemon is running
867
      return int(os.read(fd, 100))
868
  finally:
869
    os.close(fd)
870

  
871
  return None
872

  
873

  
843 874
def MatchNameComponent(key, name_list, case_sensitive=True):
844 875
  """Try to match a name against a list.
845 876

  
b/test/ganeti.utils_unittest.py
1840 1840
                             "", "x"])
1841 1841

  
1842 1842

  
1843
class TestReadLockedPidFile(unittest.TestCase):
1844
  def setUp(self):
1845
    self.tmpdir = tempfile.mkdtemp()
1846

  
1847
  def tearDown(self):
1848
    shutil.rmtree(self.tmpdir)
1849

  
1850
  def testNonExistent(self):
1851
    path = utils.PathJoin(self.tmpdir, "nonexist")
1852
    self.assert_(utils.ReadLockedPidFile(path) is None)
1853

  
1854
  def testUnlocked(self):
1855
    path = utils.PathJoin(self.tmpdir, "pid")
1856
    utils.WriteFile(path, data="123")
1857
    self.assert_(utils.ReadLockedPidFile(path) is None)
1858

  
1859
  def testLocked(self):
1860
    path = utils.PathJoin(self.tmpdir, "pid")
1861
    utils.WriteFile(path, data="123")
1862

  
1863
    fl = utils.FileLock.Open(path)
1864
    try:
1865
      fl.Exclusive(blocking=True)
1866

  
1867
      self.assertEqual(utils.ReadLockedPidFile(path), 123)
1868
    finally:
1869
      fl.Close()
1870

  
1871
    self.assert_(utils.ReadLockedPidFile(path) is None)
1872

  
1873
  def testError(self):
1874
    path = utils.PathJoin(self.tmpdir, "foobar", "pid")
1875
    utils.WriteFile(utils.PathJoin(self.tmpdir, "foobar"), data="")
1876
    # open(2) should return ENOTDIR
1877
    self.assertRaises(EnvironmentError, utils.ReadLockedPidFile, path)
1878

  
1879

  
1843 1880
if __name__ == '__main__':
1844 1881
  testutils.GanetiTestProgram()

Also available in: Unified diff