From ed01c92b2af30bbf39e5940aaa7ebba217289dac Mon Sep 17 00:00:00 2001 From: Boris Ranto Date: Sat, 5 Dec 2020 04:14:32 +0100 Subject: [PATCH] mgr/crash: Serialize command handling All the implemented commands read or write the self.crashes structure. We need to serialize them to avoid the threads from stepping over each other toes. This also makes sure that the main thread (serve method) does not interfere with the commands. Signed-off-by: Boris Ranto (cherry picked from commit d98d141c4f90520ee0b20df2ae01563cfe6e03fe) --- src/pybind/mgr/crash/module.py | 29 ++++++++++++++++------------- 1 file changed, 16 insertions(+), 13 deletions(-) diff --git a/src/pybind/mgr/crash/module.py b/src/pybind/mgr/crash/module.py index 0d22fe8f28cee..f2b65fbc37b27 100644 --- a/src/pybind/mgr/crash/module.py +++ b/src/pybind/mgr/crash/module.py @@ -6,7 +6,7 @@ import json from collections import defaultdict from prettytable import PrettyTable import re -from threading import Event +from threading import Event, Lock DATEFMT = '%Y-%m-%dT%H:%M:%S.%f' @@ -36,6 +36,7 @@ class Module(MgrModule): def __init__(self, *args, **kwargs): super(Module, self).__init__(*args, **kwargs) self.crashes = None + self.crashes_lock = Lock() self.run = True self.event = Event() @@ -46,8 +47,9 @@ class Module(MgrModule): def serve(self): self.config_notify() while self.run: - self._refresh_health_checks() - self._prune(self.retain_interval) + with self.crashes_lock: + self._refresh_health_checks() + self._prune(self.retain_interval) wait = min(MAX_WAIT, max(self.warn_recent_interval / 100, MIN_WAIT)) self.event.wait(wait) self.event.clear() @@ -95,16 +97,17 @@ class Module(MgrModule): self.set_health_checks(health_checks) def handle_command(self, inbuf, command): - if not self.crashes: - self._load_crashes() - for cmd in self.COMMANDS: - if cmd['cmd'].startswith(command['prefix']): - handler = cmd['handler'] - break - if handler is None: - return errno.EINVAL, '', 'unknown command %s' % command['prefix'] - - return handler(self, command, inbuf) + with self.crashes_lock: + if not self.crashes: + self._load_crashes() + for cmd in self.COMMANDS: + if cmd['cmd'].startswith(command['prefix']): + handler = cmd['handler'] + break + if handler is None: + return errno.EINVAL, '', 'unknown command %s' % command['prefix'] + + return handler(self, command, inbuf) def time_from_string(self, timestr): # drop the 'Z' timezone indication, it's always UTC -- 2.39.5