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