Ensure pid file is removed when metadata ns daemon receives SIGTERM
These files from the metadata namespace proxy are not being removed because delete_pid() is registered with atexit. This means it only runs when a process exits normally and won't run when a process receives a signal. This patch registers a signal handler for SIGTERM that calls exit() to make the process exit normally so delete_pid() gets called. Fixes bug: 1223250 Change-Id: I6309802e2109359560ccc084559ec8e4d310cce2
This commit is contained in:
parent
ff514f3938
commit
baf31fdeee
@ -19,6 +19,7 @@
|
||||
import atexit
|
||||
import fcntl
|
||||
import os
|
||||
import signal
|
||||
import sys
|
||||
|
||||
from neutron.agent.linux import utils
|
||||
@ -123,11 +124,15 @@ class Daemon(object):
|
||||
|
||||
# write pidfile
|
||||
atexit.register(self.delete_pid)
|
||||
signal.signal(signal.SIGTERM, self.handle_sigterm)
|
||||
self.pidfile.write(os.getpid())
|
||||
|
||||
def delete_pid(self):
|
||||
os.remove(str(self.pidfile))
|
||||
|
||||
def handle_sigterm(self, signum, frame):
|
||||
sys.exit(0)
|
||||
|
||||
def start(self):
|
||||
"""Start the daemon."""
|
||||
|
||||
|
@ -160,13 +160,16 @@ class TestDaemon(base.BaseTestCase):
|
||||
d = daemon.Daemon('pidfile')
|
||||
with mock.patch.object(d, '_fork') as fork:
|
||||
with mock.patch.object(daemon, 'atexit') as atexit:
|
||||
with mock.patch.object(daemon, 'signal') as signal:
|
||||
signal.SIGTERM = 15
|
||||
with mock.patch.object(daemon, 'sys') as sys:
|
||||
sys.stdin.fileno.return_value = 0
|
||||
sys.stdout.fileno.return_value = 1
|
||||
sys.stderr.fileno.return_value = 2
|
||||
d.daemonize()
|
||||
atexit.register.assert_called_once_with(d.delete_pid)
|
||||
|
||||
signal.signal.assert_called_once_with(15, d.handle_sigterm)
|
||||
atexit.register.assert_called_once_with(d.delete_pid)
|
||||
fork.assert_has_calls([mock.call(), mock.call()])
|
||||
|
||||
self.os.assert_has_calls([
|
||||
@ -185,6 +188,12 @@ class TestDaemon(base.BaseTestCase):
|
||||
d.delete_pid()
|
||||
self.os.remove.assert_called_once_with('pidfile')
|
||||
|
||||
def test_handle_sigterm(self):
|
||||
d = daemon.Daemon('pidfile')
|
||||
with mock.patch.object(daemon, 'sys') as sys:
|
||||
d.handle_sigterm(15, 1234)
|
||||
sys.exit.assert_called_once_with(0)
|
||||
|
||||
def test_start(self):
|
||||
self.pidfile.return_value.is_running.return_value = False
|
||||
d = daemon.Daemon('pidfile')
|
||||
|
Loading…
Reference in New Issue
Block a user