summaryrefslogtreecommitdiff
path: root/oslo_rootwrap/daemon.py
diff options
context:
space:
mode:
Diffstat (limited to 'oslo_rootwrap/daemon.py')
-rw-r--r--oslo_rootwrap/daemon.py40
1 files changed, 39 insertions, 1 deletions
diff --git a/oslo_rootwrap/daemon.py b/oslo_rootwrap/daemon.py
index cf7f03e..5982e4b 100644
--- a/oslo_rootwrap/daemon.py
+++ b/oslo_rootwrap/daemon.py
@@ -26,6 +26,7 @@ import stat
import sys
import tempfile
import threading
+import time
from oslo_rootwrap import cmd
from oslo_rootwrap import jsonrpc
@@ -44,8 +45,11 @@ class RootwrapClass(object):
def __init__(self, config, filters):
self.config = config
self.filters = filters
+ self.reset_timer()
+ self.prepare_timer(config)
def run_one_command(self, userargs, stdin=None):
+ self.reset_timer()
try:
obj = wrapper.start_subprocess(
self.filters, userargs,
@@ -73,7 +77,40 @@ class RootwrapClass(object):
err = os.fsdecode(err)
return obj.returncode, out, err
- def shutdown(self):
+ @classmethod
+ def reset_timer(cls):
+ cls.last_called = time.time()
+
+ @classmethod
+ def cancel_timer(cls):
+ try:
+ cls.timeout.cancel()
+ except RuntimeError:
+ pass
+
+ @classmethod
+ def prepare_timer(cls, config=None):
+ if config is not None:
+ cls.daemon_timeout = config.daemon_timeout
+ # Wait a bit longer to avoid rounding errors
+ timeout = max(
+ cls.last_called + cls.daemon_timeout - time.time(),
+ 0) + 1
+ if getattr(cls, 'timeout', None):
+ # Another timer is already initialized
+ return
+ cls.timeout = threading.Timer(timeout, cls.handle_timeout)
+ cls.timeout.start()
+
+ @classmethod
+ def handle_timeout(cls):
+ if cls.last_called < time.time() - cls.daemon_timeout:
+ cls.shutdown()
+
+ cls.prepare_timer()
+
+ @staticmethod
+ def shutdown():
# Suicide to force break of the main thread
os.kill(os.getpid(), signal.SIGINT)
@@ -144,6 +181,7 @@ def daemon_start(config, filters):
except Exception:
# Most likely the socket have already been closed
LOG.debug("Failed to close connection")
+ RootwrapClass.cancel_timer()
LOG.info("Waiting for all client threads to finish.")
for thread in threading.enumerate():
if thread.daemon: