]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
mgr/crash: Serialize command handling 39338/head
authorBoris Ranto <branto@redhat.com>
Sat, 5 Dec 2020 03:14:32 +0000 (04:14 +0100)
committerNathan Cutler <ncutler@suse.com>
Sun, 7 Feb 2021 12:44:28 +0000 (13:44 +0100)
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 <branto@redhat.com>
(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

index 56340dc7f608abf3ba194d0387e13b747edeb602..b9cf492950fa0134338c4da4aceabc3e3cc2a0f9 100644 (file)
@@ -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