From c196191e98cb1b43a7ea218e946d0abeea68aec3 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) Conflicts: src/pybind/mgr/crash/module.py - no "import re" in the stable branch --- 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 56340dc7f608..b9cf492950fa 100644 --- a/src/pybind/mgr/crash/module.py +++ b/src/pybind/mgr/crash/module.py @@ -4,7 +4,7 @@ import errno import json from collections import defaultdict from prettytable import PrettyTable -from threading import Event +from threading import Event, Lock DATEFMT = '%Y-%m-%d %H:%M:%S.%f' @@ -33,6 +33,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() @@ -43,8 +44,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() @@ -91,16 +93,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.47.3