From: Boris Ranto Date: Sat, 5 Dec 2020 03:14:32 +0000 (+0100) Subject: mgr/crash: Serialize command handling X-Git-Tag: v16.1.0~304^2 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=d98d141c4f90520ee0b20df2ae01563cfe6e03fe;p=ceph.git 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 --- diff --git a/src/pybind/mgr/crash/module.py b/src/pybind/mgr/crash/module.py index 0d22fe8f28ce..f2b65fbc37b2 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