Skip to content

Commit

Permalink
Merge pull request #2005 from DataDog/quentin/pidfile-check-agent-pro…
Browse files Browse the repository at this point in the history
…cess

[core] improve detection of agent process from pid
yannmh committed Nov 16, 2015
2 parents eb0154d + ef296d5 commit 70e8a18
Showing 3 changed files with 38 additions and 5 deletions.
7 changes: 4 additions & 3 deletions daemon.py
Original file line number Diff line number Diff line change
@@ -20,7 +20,7 @@
import time

# project
from utils.process import pid_exists
from utils.process import is_my_process

log = logging.getLogger(__name__)

@@ -162,12 +162,13 @@ def start(self, foreground=False):

if pid:
# Check if the pid in the pidfile corresponds to a running process
if pid_exists(pid):
# and if psutil is installed, check if it's a datadog-agent one
if is_my_process(pid):
log.error("Not starting, another instance is already running"
" (using pidfile {0})".format(self.pidfile))
sys.exit(1)
else:
log.warn('pidfile contains the pid of a stopped process.'
log.warn("pidfile doesn't contain the pid of an agent process."
' Starting normally')

log.info("Pidfile: %s" % self.pidfile)
Original file line number Diff line number Diff line change
@@ -3,17 +3,21 @@
import unittest

# project
from utils.process import pid_exists
from utils.process import is_my_process, pid_exists


class UtilsProcessTest(unittest.TestCase):
def test_my_own_pid(self):
my_pid = os.getpid()
self.assertTrue(pid_exists(my_pid))
self.assertTrue(is_my_process(my_pid))

def test_inexistant_pid(self):
# There will be one point where we finally find a free PID
for pid in xrange(30000):
if not pid_exists(pid):
return
raise Exception("Probably a bug in pid_exists or more than 30000 procs!!")

def test_existing_process(self):
self.assertFalse(is_my_process(1))
30 changes: 29 additions & 1 deletion utils/process.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
# stdlib
import errno
import inspect
import os

# 3p
@@ -9,7 +10,34 @@
psutil = None

# project
from util import Platform
from utils.platform import Platform


def is_my_process(pid):
"""
Check if the pid in the pid given corresponds to a running process
and if psutil is available, check if it's process corresponding to
the current executable
"""
pid_existence = pid_exists(pid)

if not psutil or not pid_existence:
return pid_existence

if Platform.is_windows():
# We can't check anything else on Windows
return True
else:
try:
command = psutil.Process(pid).cmdline() or []
except psutil.Error:
# If we can't communicate with the process,
# it's not an agent one
return False
# Check that the second arg contains (agent|dogstatsd).py
# see http://stackoverflow.com/a/2345265
exec_name = os.path.basename(inspect.stack()[-1][1]).lower()
return len(command) > 1 and exec_name in command[1].lower()


def pid_exists(pid):

0 comments on commit 70e8a18

Please sign in to comment.