From: Sage Weil Date: Tue, 11 Jul 2017 03:23:19 +0000 (-0400) Subject: mgr: add trivial OSDMap wrapper class X-Git-Tag: v12.2.2~61^2~104 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=4d686ee875d5bc0125426d348e044988aaca9f91;p=ceph.git mgr: add trivial OSDMap wrapper class Signed-off-by: Sage Weil (cherry picked from commit 2ef005196ba2eb49c34c32def624938c7a8beb03) --- diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index a27f286d83a3..167af7f82305 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -696,6 +696,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 diff --git a/src/mgr/MgrPyModule.cc b/src/mgr/MgrPyModule.cc index a2bf73ca3791..49b70d8a24bb 100644 --- a/src/mgr/MgrPyModule.cc +++ b/src/mgr/MgrPyModule.cc @@ -12,6 +12,7 @@ */ #include "PyState.h" +#include "PyOSDMap.h" #include "Gil.h" #include "PyFormatter.h" @@ -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(sys_path.c_str())); } diff --git a/src/mgr/PyModules.cc b/src/mgr/PyModules.cc index 501c6037c3d3..e014b382fd35 100644 --- a/src/mgr/PyModules.cc +++ b/src/mgr/PyModules.cc @@ -803,6 +803,29 @@ PyObject *PyModules::get_context() return capsule; } +static void delete_osdmap(PyObject *object) +{ + OSDMap *osdmap = static_cast(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 *modules) diff --git a/src/mgr/PyModules.h b/src/mgr/PyModules.h index ef94c3b99379..3bb5449d156b 100644 --- a/src/mgr/PyModules.h +++ b/src/mgr/PyModules.h @@ -83,6 +83,7 @@ public: const std::string svc_type, const std::string &svc_id); PyObject *get_context(); + PyObject *get_osdmap(); std::map config_cache; diff --git a/src/mgr/PyOSDMap.cc b/src/mgr/PyOSDMap.cc new file mode 100644 index 000000000000..9b1bdc4e3b79 --- /dev/null +++ b/src/mgr/PyOSDMap.cc @@ -0,0 +1,125 @@ +// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- +// vim: ts=8 sw=2 smarttab + +#include "Mgr.h" + +#include "osd/OSDMap.h" +#include "common/errno.h" +#include "common/version.h" + +#include "PyOSDMap.h" +#include "PyFormatter.h" +#include "Gil.h" + +#define dout_context g_ceph_context +#define dout_subsys ceph_subsys_mgr + +// ---------- + +static PyObject *osdmap_get_epoch(PyObject *self, PyObject *obj) +{ + OSDMap *osdmap = static_cast(PyCapsule_GetPointer(obj, nullptr)); + return PyInt_FromLong(osdmap->get_epoch()); +} + +static PyObject *osdmap_dump(PyObject *self, PyObject *obj) +{ + OSDMap *osdmap = static_cast(PyCapsule_GetPointer(obj, nullptr)); + PyFormatter f; + osdmap->dump(&f); + return f.get(); +} + + +static void delete_osdmap_incremental(PyObject *object) +{ + OSDMap::Incremental *inc = static_cast( + PyCapsule_GetPointer(object, nullptr)); + derr << __func__ << " " << inc << dendl; + delete inc; +} + +static PyObject *osdmap_new_incremental(PyObject *self, PyObject *obj) +{ + OSDMap *osdmap = static_cast(PyCapsule_GetPointer(obj, nullptr)); + + // Construct a capsule containing an OSDMap. + OSDMap::Incremental *inc = new OSDMap::Incremental; + inc->fsid = osdmap->get_fsid(); + inc->epoch = osdmap->get_epoch() + 1; + return PyCapsule_New(inc, nullptr, &delete_osdmap_incremental); +} + +static PyObject *osdmap_calc_pg_upmaps(PyObject *self, PyObject *args) +{ + PyObject *mapobj, *incobj, *pool_list; + double max_deviation = 0; + int max_iterations = 0; + if (!PyArg_ParseTuple(args, "OOdiO:calc_pg_upmaps", + &mapobj, &incobj, &max_deviation, + &max_iterations, &pool_list)) { + return nullptr; + } + + OSDMap *osdmap = static_cast(PyCapsule_GetPointer(mapobj, nullptr)); + OSDMap::Incremental *inc = static_cast( + PyCapsule_GetPointer(incobj, nullptr)); + + dout(10) << __func__ << " osdmap " << osdmap << " inc " << inc + << " max_deviation " << max_deviation + << " max_iterations " << max_iterations + << dendl; + set pools; + // FIXME: unpack pool_list and translate to pools set + int r = osdmap->calc_pg_upmaps(g_ceph_context, + max_deviation, + max_iterations, + pools, + inc); + dout(10) << __func__ << " r = " << r << dendl; + return PyInt_FromLong(r); +} + +PyMethodDef OSDMapMethods[] = { + {"get_epoch", osdmap_get_epoch, METH_O, "Get OSDMap epoch"}, + {"dump", osdmap_dump, METH_O, "Dump OSDMap::Incremental"}, + {"new_incremental", osdmap_new_incremental, METH_O, + "Create OSDMap::Incremental"}, + {"calc_pg_upmaps", osdmap_calc_pg_upmaps, METH_VARARGS, + "Calculate new pg-upmap values"}, + {NULL, NULL, 0, NULL} +}; + +// ---------- + +static PyObject *osdmap_inc_get_epoch(PyObject *self, PyObject *obj) +{ + OSDMap::Incremental *inc = static_cast( + PyCapsule_GetPointer(obj, nullptr)); + return PyInt_FromLong(inc->epoch); +} + +static PyObject *osdmap_inc_dump(PyObject *self, PyObject *obj) +{ + OSDMap::Incremental *inc = static_cast( + PyCapsule_GetPointer(obj, nullptr)); + PyFormatter f; + inc->dump(&f); + return f.get(); +} + +PyMethodDef OSDMapIncrementalMethods[] = { + {"get_epoch", osdmap_inc_get_epoch, METH_O, "Get OSDMap::Incremental epoch"}, + {"dump", osdmap_inc_dump, METH_O, "Dump OSDMap::Incremental"}, + {NULL, NULL, 0, NULL} +}; + + +// ---------- + + + +PyMethodDef CRUSHMapMethods[] = { +// {"get_epoch", osdmap_get_epoch, METH_O, "Get OSDMap epoch"}, + {NULL, NULL, 0, NULL} +}; diff --git a/src/mgr/PyOSDMap.h b/src/mgr/PyOSDMap.h new file mode 100644 index 000000000000..bfa851cd6601 --- /dev/null +++ b/src/mgr/PyOSDMap.h @@ -0,0 +1,10 @@ +// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- +// vim: ts=8 sw=2 smarttab + +#pragma once + +#include "Python.h" + +extern PyMethodDef OSDMapMethods[]; +extern PyMethodDef OSDMapIncrementalMethods[]; +extern PyMethodDef CRUSHMapMethods[]; diff --git a/src/mgr/PyState.cc b/src/mgr/PyState.cc index fb6b831de727..fe849de107e7 100644 --- a/src/mgr/PyState.cc +++ b/src/mgr/PyState.cc @@ -454,6 +454,13 @@ get_perf_schema(PyObject *self, PyObject *args) return global_handle->get_perf_schema_python(handle, type_str, svc_id); } +static PyObject * +ceph_get_osdmap(PyObject *self, PyObject *args) +{ + return global_handle->get_osdmap(); +} + + PyMethodDef CephStateMethods[] = { {"get", ceph_state_get, METH_VARARGS, "Get a cluster object"}, @@ -485,6 +492,8 @@ PyMethodDef CephStateMethods[] = { "Get the ceph version of this process"}, {"get_context", ceph_get_context, METH_NOARGS, "Get a CephContext* in a python capsule"}, + {"get_osdmap", ceph_get_osdmap, METH_NOARGS, + "Get an OSDMap handle"}, {NULL, NULL, 0, NULL} }; diff --git a/src/pybind/mgr/dashboard/module.py b/src/pybind/mgr/dashboard/module.py index 10b5c37edb30..f41b0160f84d 100644 --- a/src/pybind/mgr/dashboard/module.py +++ b/src/pybind/mgr/dashboard/module.py @@ -832,6 +832,9 @@ class Module(MgrModule): 'engine.autoreload.on': False }) + osdmap = self.get_osdmap() + log.info("latest osdmap is %d" % osdmap.get_epoch()) + static_dir = os.path.join(current_dir, 'static') conf = { "/static": { diff --git a/src/pybind/mgr/mgr_module.py b/src/pybind/mgr/mgr_module.py index 2463bafe75d8..57ea33e16601 100644 --- a/src/pybind/mgr/mgr_module.py +++ b/src/pybind/mgr/mgr_module.py @@ -1,5 +1,8 @@ import ceph_state #noqa +import ceph_osdmap #noqa +import ceph_osdmap_incremental #noqa +import ceph_crushmap #noqa import json import logging import threading @@ -30,6 +33,44 @@ class CommandResult(object): return self.r, self.outb, self.outs +class OSDMap(object): + def __init__(self, handle): + self._handle = handle + + def get_epoch(self): + return ceph_osdmap.get_epoch(self._handle) + + def dump(self): + return ceph_osdmap.dump(self._handle) + + def new_incremental(self): + return OSDMapIncremental(ceph_osdmap.new_incremental(self._handle)) + + def calc_pg_upmaps(self, inc, max_deviation=.01, max_iterations=10, pools=[]): + return ceph_osdmap.calc_pg_upmaps( + self._handle, + inc._handle, + max_deviation, max_iterations, pools) + + +class OSDMapIncremental(object): + def __init__(self, handle): + self._handle = handle + + def get_epoch(self): + return ceph_osdmap_incremental.get_epoch(self._handle) + + def dump(self): + return ceph_osdmap_incremental.dump(self._handle) + +class CRUSHMap(object): + def __init__(self, handle): + self._handle = handle + +# def get_epoch(self): +# return ceph_crushmap.get_epoch(self._handle) + + class MgrModule(object): COMMANDS = [] @@ -299,3 +340,11 @@ class MgrModule(object): :return: bool """ pass + + def get_osdmap(self): + """ + Get a handle to an OSDMap. If epoch==0, get a handle for the latest + OSDMap. + :return: OSDMap + """ + return OSDMap(ceph_state.get_osdmap())