Commit debed9ae authored by Michael Hanselmann's avatar Michael Hanselmann
Browse files

utils: Add function to read locked PID file



This is useful in combination with utils.StartDaemon and will be used for
reading the import/export daemon's PID file.
Signed-off-by: default avatarMichael Hanselmann <hansmi@google.com>
Reviewed-by: default avatarGuido Trotter <ultrotter@google.com>
parent dc101ecc
......@@ -2855,25 +2855,8 @@ def CleanupImportExport(name):
logging.info("Finalizing import/export %s", name)
status_dir = utils.PathJoin(constants.IMPORT_EXPORT_DIR, name)
pid_file = utils.PathJoin(status_dir, _IES_PID_FILE)
pid = None
try:
fd = os.open(pid_file, os.O_RDONLY)
except EnvironmentError, err:
if err.errno != errno.ENOENT:
raise
# PID file doesn't exist
else:
try:
try:
# Try to acquire lock
utils.LockFile(fd)
except errors.LockError:
# Couldn't lock, daemon is running
pid = int(os.read(fd, 100))
finally:
os.close(fd)
pid = utils.ReadLockedPidFile(utils.PathJoin(status_dir, _IES_PID_FILE))
if pid:
logging.info("Import/export %s is still running with PID %s",
......
......@@ -840,6 +840,37 @@ def ReadPidFile(pidfile):
return pid
def ReadLockedPidFile(path):
"""Reads a locked PID file.
This can be used together with L{StartDaemon}.
@type path: string
@param path: Path to PID file
@return: PID as integer or, if file was unlocked or couldn't be opened, None
"""
try:
fd = os.open(path, os.O_RDONLY)
except EnvironmentError, err:
if err.errno == errno.ENOENT:
# PID file doesn't exist
return None
raise
try:
try:
# Try to acquire lock
LockFile(fd)
except errors.LockError:
# Couldn't lock, daemon is running
return int(os.read(fd, 100))
finally:
os.close(fd)
return None
def MatchNameComponent(key, name_list, case_sensitive=True):
"""Try to match a name against a list.
......
......@@ -1840,5 +1840,42 @@ class TestLineSplitter(unittest.TestCase):
"", "x"])
class TestReadLockedPidFile(unittest.TestCase):
def setUp(self):
self.tmpdir = tempfile.mkdtemp()
def tearDown(self):
shutil.rmtree(self.tmpdir)
def testNonExistent(self):
path = utils.PathJoin(self.tmpdir, "nonexist")
self.assert_(utils.ReadLockedPidFile(path) is None)
def testUnlocked(self):
path = utils.PathJoin(self.tmpdir, "pid")
utils.WriteFile(path, data="123")
self.assert_(utils.ReadLockedPidFile(path) is None)
def testLocked(self):
path = utils.PathJoin(self.tmpdir, "pid")
utils.WriteFile(path, data="123")
fl = utils.FileLock.Open(path)
try:
fl.Exclusive(blocking=True)
self.assertEqual(utils.ReadLockedPidFile(path), 123)
finally:
fl.Close()
self.assert_(utils.ReadLockedPidFile(path) is None)
def testError(self):
path = utils.PathJoin(self.tmpdir, "foobar", "pid")
utils.WriteFile(utils.PathJoin(self.tmpdir, "foobar"), data="")
# open(2) should return ENOTDIR
self.assertRaises(EnvironmentError, utils.ReadLockedPidFile, path)
if __name__ == '__main__':
testutils.GanetiTestProgram()
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment