pg_map.dump_pool_stats_full(osd_map, nullptr, &f, true);
});
return f.get();
+ } else if (what == "pg_stats") {
+ cluster_state.with_pgmap(
+ [&f, &tstate](const PGMap &pg_map) {
+ PyEval_RestoreThread(tstate);
+ pg_map.dump_pg_stats(&f, false);
+ });
+ return f.get();
+ } else if (what == "pool_stats") {
+ cluster_state.with_pgmap(
+ [&f, &tstate](const PGMap &pg_map) {
+ PyEval_RestoreThread(tstate);
+ pg_map.dump_pool_stats(&f);
+ });
+ return f.get();
} else if (what == "osd_stats") {
cluster_state.with_pgmap(
[&f, &tstate](const PGMap &pg_map) {
-
"""
Balance PG distribution across OSDs.
"""
TIME_FORMAT = '%Y-%m-%d_%H:%M:%S'
class MappingState:
- def __init__(self, osdmap, pg_dump, desc=''):
+ def __init__(self, osdmap, raw_pg_stats, raw_pool_stats, desc=''):
self.desc = desc
self.osdmap = osdmap
self.osdmap_dump = self.osdmap.dump()
self.crush = osdmap.get_crush()
self.crush_dump = self.crush.dump()
- self.pg_dump = pg_dump
+ self.raw_pg_stats = raw_pg_stats
+ self.raw_pool_stats = raw_pool_stats
self.pg_stat = {
- i['pgid']: i['stat_sum'] for i in pg_dump.get('pg_stats', [])
+ i['pgid']: i['stat_sum'] for i in raw_pg_stats.get('pg_stats', [])
}
osd_poolids = [p['pool'] for p in self.osdmap_dump.get('pools', [])]
- pg_poolids = [p['poolid'] for p in pg_dump.get('pool_stats', [])]
+ pg_poolids = [p['poolid'] for p in raw_pool_stats.get('pool_stats', [])]
self.poolids = set(osd_poolids) & set(pg_poolids)
self.pg_up = {}
self.pg_up_by_poolid = {}
self.inc.set_osd_reweights(self.osd_weights)
self.inc.set_crush_compat_weight_set_weights(self.compat_ws)
return MappingState(self.initial.osdmap.apply_incremental(self.inc),
- self.initial.pg_dump,
+ self.initial.raw_pg_stats,
+ self.initial.raw_pool_stats,
'plan %s final' % self.name)
def dump(self):
return (-errno.EPERM, '', warn)
elif command['mode'] == 'crush-compat':
ms = MappingState(self.get_osdmap(),
- self.get("pg_dump"),
+ self.get("pg_stats"),
+ self.get("pool_stats"),
'initialize compat weight-set')
self.get_compat_weight_set_weights(ms) # ignore error
self.set_module_option('mode', command['mode'])
if option not in valid_pool_names:
return (-errno.EINVAL, '', 'option "%s" not a plan or a pool' % option)
pools.append(option)
- ms = MappingState(osdmap, self.get("pg_dump"), 'pool "%s"' % option)
+ ms = MappingState(osdmap, self.get("pg_stats"), self.get("pool_stats"), 'pool "%s"' % option)
else:
pools = plan.pools
if plan.mode == 'upmap':
# we use a basic version of Plan without keeping the obvious
# *redundant* MS member.
# Hence ms might not be accurate here since we are basically
- # using an old snapshotted osdmap vs a fresh copy of pg_dump.
+ # using an old snapshotted osdmap vs a fresh copy of pg_stats.
# It should not be a big deal though..
ms = MappingState(plan.osdmap,
- self.get("pg_dump"),
+ self.get("pg_stats"),
+ self.get("pool_stats"),
'plan "%s"' % plan.name)
else:
ms = plan.final_state()
else:
ms = MappingState(self.get_osdmap(),
- self.get("pg_dump"),
+ self.get("pg_stats"),
+ self.get("pool_stats"),
'current cluster')
return (0, self.evaluate(ms, pools, verbose=verbose), '')
elif command['prefix'] == 'balancer optimize':
if mode == 'upmap':
# drop unnecessary MS member for upmap mode.
# this way we could effectively eliminate the usage of a
- # complete pg_dump, which can become horribly inefficient
+ # complete pg_stats, which can become horribly inefficient
# as pg_num grows..
plan = Plan(name, mode, osdmap, pools)
else:
plan = MsPlan(name,
mode,
MappingState(osdmap,
- self.get("pg_dump"),
+ self.get("pg_stats"),
+ self.get("pool_stats"),
'plan %s initial' % name),
pools)
return plan
:param str data_name: Valid things to fetch are osd_crush_map_text,
osd_map, osd_map_tree, osd_map_crush, config, mon_map, fs_map,
osd_metadata, pg_summary, io_rate, pg_dump, df, osd_stats,
- health, mon_status, devices, device <devid>.
+ health, mon_status, devices, device <devid>, pg_stats,
+ pool_stats.
Note:
All these structures have their own JSON representations: experiment
def which_osds(self):
return self. _which_osds
- def pg_update(self, pg_dump, log):
+ def pg_update(self, raw_pg_stats, log):
# type: (Dict, Any) -> None
# FIXME: O(pg_num) in python
# FIXME: far more fields getting pythonized than we really care about
# Sanity check to see if there are any missing PGs and to assign
# empty array and dictionary if there hasn't been any recovery
- pg_to_state = dict([(p['pgid'], p) for p in pg_dump['pg_stats']]) # type: Dict[str, Any]
+ pg_to_state = dict([(p['pgid'], p) for p in raw_pg_stats['pg_stats']]) # type: Dict[str, Any]
if self._original_bytes_recovered is None:
self._original_bytes_recovered = {}
missing_pgs = []
which_osds=[osd_id],
start_epoch=self.get_osdmap().get_epoch()
)
- r_ev.pg_update(self.get("pg_dump"), self.log)
+ r_ev.pg_update(self.get("pg_stats"), self.log)
self._events[r_ev.id] = r_ev
def _osdmap_changed(self, old_osdmap, new_osdmap):
))
self._osdmap_changed(old_osdmap, self._latest_osdmap)
elif notify_type == "pg_summary":
- data = self.get("pg_dump")
+ data = self.get("pg_stats")
for ev_id in list(self._events):
ev = self._events[ev_id]
if isinstance(ev, PgRecoveryEvent):