From: David Zafman Date: Tue, 22 Oct 2019 22:24:05 +0000 (-0700) Subject: mgr: Release GIL before calling OSDMap::calc_pg_upmaps() X-Git-Tag: v15.1.0~1000^2~2 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=e2a35e8c8e9f381a635ad0ca01326a2c512590a9;p=ceph.git mgr: Release GIL before calling OSDMap::calc_pg_upmaps() Prevent optimize and execute commands from running with active balancer Fixes: https://tracker.ceph.com/issues/42432 Signed-off-by: David Zafman --- diff --git a/src/mgr/PyOSDMap.cc b/src/mgr/PyOSDMap.cc index 5c249512de0..dd67ae223e4 100644 --- a/src/mgr/PyOSDMap.cc +++ b/src/mgr/PyOSDMap.cc @@ -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); } diff --git a/src/pybind/mgr/balancer/module.py b/src/pybind/mgr/balancer/module.py index 4755adb23cf..eb3d4b77d3b 100644 --- a/src/pybind/mgr/balancer/module.py +++ b/src/pybind/mgr/balancer/module.py @@ -407,6 +407,7 @@ class Module(MgrModule): run = True plans = {} mode = '' + optimizing = False def __init__(self, *args, **kwargs): super(Module, self).__init__(*args, **kwargs) @@ -519,6 +520,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'] @@ -532,10 +538,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']) @@ -556,6 +561,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']) @@ -625,10 +635,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() @@ -639,7 +650,6 @@ class Module(MgrModule): self.get("pg_dump"), 'plan %s initial' % name), pools) - self.plans[name] = plan return plan def plan_rm(self, name): diff --git a/src/test/cli-integration/balancer/misplaced.t b/src/test/cli-integration/balancer/misplaced.t index 59a2a10d07d..5ab21ff7d7a 100644 --- a/src/test/cli-integration/balancer/misplaced.t +++ b/src/test/cli-integration/balancer/misplaced.t @@ -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 [