]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
mgr: Release GIL before calling OSDMap::calc_pg_upmaps()
authorDavid Zafman <dzafman@redhat.com>
Tue, 22 Oct 2019 22:24:05 +0000 (15:24 -0700)
committerDavid Zafman <dzafman@redhat.com>
Fri, 15 Nov 2019 17:17:55 +0000 (09:17 -0800)
Prevent optimize and execute commands from running with active balancer

Fixes: https://tracker.ceph.com/issues/42432
Signed-off-by: David Zafman <dzafman@redhat.com>
(cherry picked from commit e2a35e8c8e9f381a635ad0ca01326a2c512590a9)

src/mgr/PyOSDMap.cc
src/pybind/mgr/balancer/module.py
src/test/cli-integration/balancer/misplaced.t

index 5c249512de020ddb63fe1c30164d6d3437ec426e..dd67ae223e4a29e2e5d738bcfaffc45f5f652666 100644 (file)
@@ -147,11 +147,13 @@ static PyObject *osdmap_calc_pg_upmaps(BasePyOSDMap* self, PyObject *args)
           << " max_iterations " << max_iterations
           << " pools " << pools
           << dendl;
+  PyThreadState *tstate = PyEval_SaveThread();
   int r = self->osdmap->calc_pg_upmaps(g_ceph_context,
                                 max_deviation,
                                 max_iterations,
                                 pools,
                                 incobj->inc);
+  PyEval_RestoreThread(tstate);
   dout(10) << __func__ << " r = " << r << dendl;
   return PyInt_FromLong(r);
 }
index 08e2b6654f47ce2fa7315eb2c58efcc74867f152..c42693895cc8494d83086a7cf3e5a21547af0d91 100644 (file)
@@ -403,6 +403,7 @@ class Module(MgrModule):
     run = True
     plans = {}
     mode = ''
+    optimizing = False
 
     def __init__(self, *args, **kwargs):
         super(Module, self).__init__(*args, **kwargs)
@@ -515,6 +516,11 @@ class Module(MgrModule):
                                   'current cluster')
             return (0, self.evaluate(ms, pools, verbose=verbose), '')
         elif command['prefix'] == 'balancer optimize':
+            # The GIL can be release by the active balancer, so disallow when active
+            if self.active:
+                return (-errno.EINVAL, '', 'Balancer enabled, disable to optimize manually')
+            if self.optimizing:
+                return (-errno.EINVAL, '', 'Balancer finishing up....try again')
             pools = []
             if 'pools' in command:
                 pools = command['pools']
@@ -528,10 +534,9 @@ class Module(MgrModule):
                 return (-errno.EINVAL, '', 'pools %s not found' % invalid_pool_names)
             plan = self.plan_create(command['plan'], osdmap, pools)
             r, detail = self.optimize(plan)
-            # remove plan if we are currently unable to find an optimization
-            # or distribution is already perfect
-            if r:
-                self.plan_rm(command['plan'])
+            # Add plan if an optimization was created
+            if not r:
+                self.plans[command['plan']] = plan
             return (r, '', detail)
         elif command['prefix'] == 'balancer rm':
             self.plan_rm(command['plan'])
@@ -552,6 +557,11 @@ class Module(MgrModule):
                 return (-errno.ENOENT, '', 'plan %s not found' % command['plan'])
             return (0, plan.show(), '')
         elif command['prefix'] == 'balancer execute':
+            # The GIL can be release by the active balancer, so disallow when active
+            if self.active:
+                return (-errno.EINVAL, '', 'Balancer enabled, disable to execute a plan')
+            if self.optimizing:
+                return (-errno.EINVAL, '', 'Balancer finishing up....try again')
             plan = self.plans.get(command['plan'])
             if not plan:
                 return (-errno.ENOENT, '', 'plan %s not found' % command['plan'])
@@ -621,10 +631,11 @@ class Module(MgrModule):
                     final = [int(p) for p in final]
                     final = [pool_name_by_id[p] for p in final if p in pool_name_by_id]
                 plan = self.plan_create(name, osdmap, final)
+                self.optimizing = True
                 r, detail = self.optimize(plan)
                 if r == 0:
                     self.execute(plan)
-                self.plan_rm(name)
+                self.optimizing = False
             self.log.debug('Sleeping for %d', sleep_interval)
             self.event.wait(sleep_interval)
             self.event.clear()
@@ -635,7 +646,6 @@ class Module(MgrModule):
                                  self.get("pg_dump"),
                                  'plan %s initial' % name),
                     pools)
-        self.plans[name] = plan
         return plan
 
     def plan_rm(self, name):
index 59a2a10d07dddca2846e68a6f8112cdeb232f180..5ab21ff7d7ad68fcbc0e4c395a13c042df68d568 100644 (file)
@@ -10,6 +10,8 @@
   $ ceph config set osd.* target_max_misplaced_ratio .07
   $ ceph balancer eval
   current cluster score [0-9]*\.?[0-9]+.* (re)
+# Turn off active balancer to use manual commands
+  $ ceph balancer off
   $ ceph balancer optimize test_plan balancer_opt
   $ ceph balancer ls
   [