]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
mgr/crash: Serialize command handling 38592/head
authorBoris Ranto <branto@redhat.com>
Sat, 5 Dec 2020 03:14:32 +0000 (04:14 +0100)
committerLaura Paduano <lpaduano@suse.com>
Thu, 17 Dec 2020 14:02:43 +0000 (15:02 +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)

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