Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

implement 'do_osd_weight' in balancer module #56

Open
wants to merge 20 commits into
base: wip-balancer
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
ba7e43a
mgr/PyModules: add 'pg_status' dump
liewegas Jul 11, 2017
7686fd1
mgr/PyModules: add 'pg_dump' get
liewegas Jul 27, 2017
4337ec8
mgr: add trivial OSDMap wrapper class
liewegas Jul 11, 2017
57ba13f
pybind/mgr/mgr_module: add default arg to get_config
liewegas Jul 11, 2017
4f6305f
pybind/mgr/balancer: add balancer module
liewegas Jul 11, 2017
f7f017a
pybind/mgr/balancer: do upmap by pool, in random order
liewegas Jul 23, 2017
826b10e
crush/CrushWrapper: refactor get_rule_weight_osd_map to work with roo…
liewegas Jul 23, 2017
626059d
crush/CrushWrapper: fix output arg for find_{takes,roots}()
liewegas Jul 23, 2017
1b8335f
crush/CrushWrapper: rule_has_take
liewegas Jul 27, 2017
19ab2a7
mgr/PyOSDMap: get_crush, find_takes, get_take_weight_osd_map
liewegas Jul 23, 2017
2905b7b
mgr/PyOSDMap: OSDMap.map_pool_pgs_up, CRUSHMap.get_item_name
liewegas Jul 28, 2017
eb19389
pybind/mgr/balancer: rough framework
liewegas Aug 3, 2017
a14d20f
...
liewegas Aug 4, 2017
930ca8b
pybind/mgr/balancer: make 'crush-compat' sort of work
liewegas Aug 4, 2017
b3f9a72
src/pybind/mgr/balancer/module.py: improve scoring method
SpandanKumarSahu Aug 6, 2017
372bf39
Merge pull request #59 from SpandanKumarSahu/balancer_score
liewegas Aug 7, 2017
1ac2a87
pybind/mgr/balancer: make auto mode work
liewegas Aug 8, 2017
34729c5
pybind/mgr/balancer: make auto mode work
liewegas Aug 8, 2017
6cf5c1c
src/pybind/mgr/balancer/module.py: implement 'do_osd_weight'
SpandanKumarSahu Jul 29, 2017
6bc153f
src/mon/MonCommands.h: add 'reweight-by-pg' and 'reweight-by-utilizat…
SpandanKumarSahu Jul 29, 2017
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -688,6 +688,7 @@ if (WITH_MGR)
mgr/ClusterState.cc
mgr/PyModules.cc
mgr/PyFormatter.cc
mgr/PyOSDMap.cc
mgr/PyState.cc
mgr/MgrPyModule.cc
mgr/MgrStandby.cc
Expand Down
2 changes: 1 addition & 1 deletion src/crush/CrushTreeDumper.h
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ namespace CrushTreeDumper {
explicit Dumper(const CrushWrapper *crush_,
const name_map_t& weight_set_names_)
: crush(crush_), weight_set_names(weight_set_names_) {
crush->find_nonshadow_roots(roots);
crush->find_nonshadow_roots(&roots);
root = roots.begin();
}

Expand Down
100 changes: 62 additions & 38 deletions src/crush/CrushWrapper.cc
Original file line number Diff line number Diff line change
Expand Up @@ -291,31 +291,31 @@ int CrushWrapper::rename_bucket(const string& srcname,
return set_item_name(oldid, dstname);
}

void CrushWrapper::find_takes(set<int>& roots) const
void CrushWrapper::find_takes(set<int> *roots) const
{
for (unsigned i=0; i<crush->max_rules; i++) {
crush_rule *r = crush->rules[i];
if (!r)
continue;
for (unsigned j=0; j<r->len; j++) {
if (r->steps[j].op == CRUSH_RULE_TAKE)
roots.insert(r->steps[j].arg1);
roots->insert(r->steps[j].arg1);
}
}
}

void CrushWrapper::find_roots(set<int>& roots) const
void CrushWrapper::find_roots(set<int> *roots) const
{
for (int i = 0; i < crush->max_buckets; i++) {
if (!crush->buckets[i])
continue;
crush_bucket *b = crush->buckets[i];
if (!_search_item_exists(b->id))
roots.insert(b->id);
roots->insert(b->id);
}
}

void CrushWrapper::find_nonshadow_roots(set<int>& roots) const
void CrushWrapper::find_nonshadow_roots(set<int> *roots) const
{
for (int i = 0; i < crush->max_buckets; i++) {
if (!crush->buckets[i])
Expand All @@ -326,7 +326,7 @@ void CrushWrapper::find_nonshadow_roots(set<int>& roots) const
const char *name = get_item_name(b->id);
if (name && !is_valid_crush_name(name))
continue;
roots.insert(b->id);
roots->insert(b->id);
}
}

Expand Down Expand Up @@ -1381,7 +1381,7 @@ bool CrushWrapper::class_is_in_use(int class_id)
int CrushWrapper::populate_classes()
{
set<int> roots;
find_roots(roots);
find_roots(&roots);
for (auto &r : roots) {
if (r >= 0)
continue;
Expand All @@ -1405,7 +1405,7 @@ int CrushWrapper::cleanup_classes()
int CrushWrapper::trim_roots_with_class(bool unused)
{
set<int> roots;
find_roots(roots);
find_roots(&roots);
for (auto &r : roots) {
if (r >= 0)
continue;
Expand Down Expand Up @@ -1449,7 +1449,7 @@ int32_t CrushWrapper::_alloc_class_id() const {
void CrushWrapper::reweight(CephContext *cct)
{
set<int> roots;
find_roots(roots);
find_roots(&roots);
for (set<int>::iterator p = roots.begin(); p != roots.end(); ++p) {
if (*p >= 0)
continue;
Expand Down Expand Up @@ -1577,7 +1577,56 @@ int CrushWrapper::add_simple_rule(
rule_type, -1, err);
}

int CrushWrapper::get_rule_weight_osd_map(unsigned ruleno, map<int,float> *pmap)
float CrushWrapper::_get_take_weight_osd_map(int root,
map<int,float> *pmap) const
{
float sum = 0.0;
list<int> q;
q.push_back(root);
//breadth first iterate the OSD tree
while (!q.empty()) {
int bno = q.front();
q.pop_front();
crush_bucket *b = crush->buckets[-1-bno];
assert(b);
for (unsigned j=0; j<b->size; ++j) {
int item_id = b->items[j];
if (item_id >= 0) { //it's an OSD
float w = crush_get_bucket_item_weight(b, j);
(*pmap)[item_id] = w;
sum += w;
} else { //not an OSD, expand the child later
q.push_back(item_id);
}
}
}
return sum;
}

void CrushWrapper::_normalize_weight_map(float sum,
const map<int,float>& m,
map<int,float> *pmap) const
{
for (auto& p : m) {
map<int,float>::iterator q = pmap->find(p.first);
if (q == pmap->end()) {
(*pmap)[p.first] = p.second / sum;
} else {
q->second += p.second / sum;
}
}
}

int CrushWrapper::get_take_weight_osd_map(int root, map<int,float> *pmap) const
{
map<int,float> m;
float sum = _get_take_weight_osd_map(root, &m);
_normalize_weight_map(sum, m, pmap);
return 0;
}

int CrushWrapper::get_rule_weight_osd_map(unsigned ruleno,
map<int,float> *pmap) const
{
if (ruleno >= crush->max_rules)
return -ENOENT;
Expand All @@ -1600,35 +1649,10 @@ int CrushWrapper::get_rule_weight_osd_map(unsigned ruleno, map<int,float> *pmap)
m[n] = 1.0;
sum = 1.0;
} else {
list<int> q;
q.push_back(n);
//breadth first iterate the OSD tree
while (!q.empty()) {
int bno = q.front();
q.pop_front();
crush_bucket *b = crush->buckets[-1-bno];
assert(b);
for (unsigned j=0; j<b->size; ++j) {
int item_id = b->items[j];
if (item_id >= 0) { //it's an OSD
float w = crush_get_bucket_item_weight(b, j);
m[item_id] = w;
sum += w;
} else { //not an OSD, expand the child later
q.push_back(item_id);
}
}
}
}
}
for (map<int,float>::iterator p = m.begin(); p != m.end(); ++p) {
map<int,float>::iterator q = pmap->find(p->first);
if (q == pmap->end()) {
(*pmap)[p->first] = p->second / sum;
} else {
q->second += p->second / sum;
sum += _get_take_weight_osd_map(n, &m);
}
}
_normalize_weight_map(sum, m, pmap);
}

return 0;
Expand Down Expand Up @@ -2363,7 +2387,7 @@ namespace {

void dump(Formatter *f) {
set<int> roots;
crush->find_roots(roots);
crush->find_roots(&roots);
for (set<int>::iterator root = roots.begin(); root != roots.end(); ++root) {
dump_item(Item(*root, 0, 0, crush->get_bucket_weightf(*root)), f);
}
Expand Down
37 changes: 33 additions & 4 deletions src/crush/CrushWrapper.h
Original file line number Diff line number Diff line change
Expand Up @@ -588,22 +588,22 @@ class CrushWrapper {
*
* Note that these may not be parentless roots.
*/
void find_takes(set<int>& roots) const;
void find_takes(set<int> *roots) const;

/**
* find tree roots
*
* These are parentless nodes in the map.
*/
void find_roots(set<int>& roots) const;
void find_roots(set<int> *roots) const;

/**
* find tree roots that are not shadow (device class) items
*
* These are parentless nodes in the map that are not shadow
* items for device classes.
*/
void find_nonshadow_roots(set<int>& roots) const;
void find_nonshadow_roots(set<int> *roots) const;

/**
* see if an item is contained within a subtree
Expand Down Expand Up @@ -965,6 +965,17 @@ class CrushWrapper {
return true;
return false;
}
bool rule_has_take(unsigned ruleno, int take) const {
if (!crush) return false;
crush_rule *rule = get_rule(ruleno);
for (unsigned i = 0; i < rule->len; ++i) {
if (rule->steps[i].op == CRUSH_RULE_TAKE &&
rule->steps[i].arg1 == take) {
return true;
}
}
return false;
}
int get_rule_len(unsigned ruleno) const {
crush_rule *r = get_rule(ruleno);
if (IS_ERR(r)) return PTR_ERR(r);
Expand Down Expand Up @@ -1006,6 +1017,12 @@ class CrushWrapper {
return s->arg2;
}

private:
float _get_take_weight_osd_map(int root, map<int,float> *pmap) const;
void _normalize_weight_map(float sum, const map<int,float>& m,
map<int,float> *pmap) const;

public:
/**
* calculate a map of osds to weights for a given rule
*
Expand All @@ -1016,7 +1033,19 @@ class CrushWrapper {
* @param pmap [out] map of osd to weight
* @return 0 for success, or negative error code
*/
int get_rule_weight_osd_map(unsigned ruleno, map<int,float> *pmap);
int get_rule_weight_osd_map(unsigned ruleno, map<int,float> *pmap) const;

/**
* calculate a map of osds to weights for a given starting root
*
* Generate a map of which OSDs get how much relative weight for a
* given starting root
*
* @param root node
* @param pmap [out] map of osd to weight
* @return 0 for success, or negative error code
*/
int get_take_weight_osd_map(int root, map<int,float> *pmap) const;

/* modifiers */

Expand Down
4 changes: 4 additions & 0 deletions src/mgr/MgrPyModule.cc
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
*/

#include "PyState.h"
#include "PyOSDMap.h"
#include "Gil.h"

#include "PyFormatter.h"
Expand Down Expand Up @@ -109,6 +110,9 @@ MgrPyModule::MgrPyModule(const std::string &module_name_, const std::string &sys
}
// Populate python namespace with callable hooks
Py_InitModule("ceph_state", CephStateMethods);
Py_InitModule("ceph_osdmap", OSDMapMethods);
Py_InitModule("ceph_osdmap_incremental", OSDMapIncrementalMethods);
Py_InitModule("ceph_crushmap", CRUSHMapMethods);

PySys_SetPath(const_cast<char*>(sys_path.c_str()));
}
Expand Down
40 changes: 39 additions & 1 deletion src/mgr/PyModules.cc
Original file line number Diff line number Diff line change
Expand Up @@ -254,7 +254,22 @@ PyObject *PyModules::get_python(const std::string &what)
}
);
return f.get();

} else if (what == "pg_status") {
PyFormatter f;
cluster_state.with_pgmap(
[&f](const PGMap &pg_map) {
pg_map.print_summary(&f, nullptr);
}
);
return f.get();
} else if (what == "pg_dump") {
PyFormatter f;
cluster_state.with_pgmap(
[&f](const PGMap &pg_map) {
pg_map.dump(&f);
}
);
return f.get();
} else if (what == "df") {
PyFormatter f;

Expand Down Expand Up @@ -771,6 +786,29 @@ PyObject *PyModules::get_context()
return capsule;
}

static void delete_osdmap(PyObject *object)
{
OSDMap *osdmap = static_cast<OSDMap*>(PyCapsule_GetPointer(object, nullptr));
assert(osdmap);
dout(10) << __func__ << " " << osdmap << dendl;
delete osdmap;
}

PyObject *PyModules::get_osdmap()
{
PyThreadState *tstate = PyEval_SaveThread();
Mutex::Locker l(lock);
PyEval_RestoreThread(tstate);

// Construct a capsule containing an OSDMap.
OSDMap *newmap = new OSDMap;
cluster_state.with_osdmap([&](const OSDMap& o) {
newmap->deepish_copy_from(o);
});
dout(10) << __func__ << " " << newmap << dendl;
return PyCapsule_New(newmap, nullptr, &delete_osdmap);
}

static void _list_modules(
const std::string path,
std::set<std::string> *modules)
Expand Down
1 change: 1 addition & 0 deletions src/mgr/PyModules.h
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@ class PyModules
const std::string svc_type,
const std::string &svc_id);
PyObject *get_context();
PyObject *get_osdmap();

std::map<std::string, std::string> config_cache;

Expand Down
Loading