Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[core] improve detection of agent process from pid #2005

Merged
merged 1 commit into from
Nov 16, 2015
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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):