]> git.apps.os.sepia.ceph.com Git - ceph-ci.git/commitdiff
mgr/crash: Serialize command handling
authorBoris Ranto <branto@redhat.com>
Sat, 5 Dec 2020 03:14:32 +0000 (04:14 +0100)
committerBoris Ranto <branto@redhat.com>
Sat, 5 Dec 2020 03:14:35 +0000 (04:14 +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>
src/pybind/mgr/crash/module.py

index 0d22fe8f28cee10d65992095e2e4fc985a42edf3..f2b65fbc37b275d4c96699e96ad7abe3de6d63cd 100644 (file)
@@ -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