From: xie xingguo Date: Fri, 26 Jan 2018 08:08:41 +0000 (+0800) Subject: mgr/balancer: pool-specific optimization support X-Git-Tag: v13.0.2~395^2~1 X-Git-Url: http://git.apps.os.sepia.ceph.com/?a=commitdiff_plain;h=4ca3eb289276d4fcaf00e83d0388c58c77e76093;p=ceph.git mgr/balancer: pool-specific optimization support This currently only works for upmap. Signed-off-by: xie xingguo --- diff --git a/src/mgr/PyOSDMap.cc b/src/mgr/PyOSDMap.cc index 925126a7175a1..e4fdd8f5a1526 100644 --- a/src/mgr/PyOSDMap.cc +++ b/src/mgr/PyOSDMap.cc @@ -121,13 +121,32 @@ static PyObject *osdmap_calc_pg_upmaps(BasePyOSDMap* self, PyObject *args) &max_iterations, &pool_list)) { return nullptr; } + if (!PyList_CheckExact(pool_list)) { + derr << __func__ << " pool_list not a list" << dendl; + return nullptr; + } + set pools; + for (auto i = 0; i < PyList_Size(pool_list); ++i) { + PyObject *pool_name = PyList_GET_ITEM(pool_list, i); + if (!PyString_Check(pool_name)) { + derr << __func__ << " " << pool_name << " not a string" << dendl; + return nullptr; + } + auto pool_id = self->osdmap->lookup_pg_pool_name( + PyString_AsString(pool_name)); + if (pool_id < 0) { + derr << __func__ << " pool '" << PyString_AsString(pool_name) + << "' does not exist" << dendl; + return nullptr; + } + pools.insert(pool_id); + } dout(10) << __func__ << " osdmap " << self->osdmap << " inc " << incobj->inc << " max_deviation " << max_deviation << " max_iterations " << max_iterations + << " pools " << pools << dendl; - set pools; - // FIXME: unpack pool_list and translate to pools set int r = self->osdmap->calc_pg_upmaps(g_ceph_context, max_deviation, max_iterations, diff --git a/src/pybind/mgr/balancer/module.py b/src/pybind/mgr/balancer/module.py index 0253de9245490..45e26069b1403 100644 --- a/src/pybind/mgr/balancer/module.py +++ b/src/pybind/mgr/balancer/module.py @@ -50,10 +50,11 @@ class MappingState: return 0.0 class Plan: - def __init__(self, name, ms): + def __init__(self, name, ms, pools): self.mode = 'unknown' self.name = name self.initial = ms + self.pools = pools self.osd_weights = {} self.compat_ws = {} @@ -222,7 +223,7 @@ class Module(MgrModule): "perm": "r", }, { - "cmd": "balancer optimize name=plan,type=CephString", + "cmd": "balancer optimize name=plan,type=CephString name=pools,type=CephString,n=N,req=false", "desc": "Run optimizer to create a new plan", "perm": "rw", }, @@ -299,7 +300,18 @@ class Module(MgrModule): 'current cluster') return (0, self.evaluate(ms, verbose=verbose), '') elif command['prefix'] == 'balancer optimize': - plan = self.plan_create(command['plan']) + pools = [] + if 'pools' in command: + pools = command['pools'] + osdmap = self.get_osdmap() + valid_pool_names = [p['pool_name'] for p in osdmap.dump().get('pools', [])] + invalid_pool_names = [] + for p in pools: + if p not in valid_pool_names: + invalid_pool_names.append(p) + if len(invalid_pool_names): + return (-errno.EINVAL, '', 'pools %s not found' % invalid_pool_names) + plan = self.plan_create(command['plan'], osdmap, pools) self.optimize(plan) return (0, '', '') elif command['prefix'] == 'balancer rm': @@ -355,7 +367,7 @@ class Module(MgrModule): if self.active and self.time_in_interval(timeofday, begin_time, end_time): self.log.debug('Running') name = 'auto_%s' % time.strftime(TIME_FORMAT, time.gmtime()) - plan = self.plan_create(name) + plan = self.plan_create(name, self.get_osdmap(), []) if self.optimize(plan): self.execute(plan) self.plan_rm(name) @@ -363,10 +375,12 @@ class Module(MgrModule): self.event.wait(sleep_interval) self.event.clear() - def plan_create(self, name): - plan = Plan(name, MappingState(self.get_osdmap(), - self.get("pg_dump"), - 'plan %s initial' % name)) + def plan_create(self, name, osdmap, pools): + plan = Plan(name, + MappingState(osdmap, + self.get("pg_dump"), + 'plan %s initial' % name), + pools) self.plans[name] = plan return plan @@ -610,7 +624,10 @@ class Module(MgrModule): max_deviation = float(self.get_config('upmap_max_deviation', .01)) ms = plan.initial - pools = [str(i['pool_name']) for i in ms.osdmap_dump.get('pools',[])] + if len(plan.pools): + pools = plan.pools + else: # all + pools = [str(i['pool_name']) for i in ms.osdmap_dump.get('pools',[])] if len(pools) == 0: self.log.info('no pools, nothing to do') return False