#include "Mgr.h"
#include "mon/MonClient.h"
+#include "common/errno.h"
#include "common/version.h"
#include "PyState.h"
+#include "Gil.h"
#define dout_context g_ceph_context
+#define dout_subsys ceph_subsys_mgr
PyModules *global_handle = NULL;
{
PyObject *python_completion;
const std::string tag;
+ PyThreadState *pThreadState;
public:
std::string outs;
bufferlist outbl;
- MonCommandCompletion(PyObject* ev, const std::string &tag_)
- : python_completion(ev), tag(tag_)
+ MonCommandCompletion(PyObject* ev, const std::string &tag_, PyThreadState *ts_)
+ : python_completion(ev), tag(tag_), pThreadState(ts_)
{
assert(python_completion != nullptr);
Py_INCREF(python_completion);
void finish(int r) override
{
- PyGILState_STATE gstate;
- gstate = PyGILState_Ensure();
-
- auto set_fn = PyObject_GetAttrString(python_completion, "complete");
- assert(set_fn != nullptr);
-
- auto pyR = PyInt_FromLong(r);
- auto pyOutBl = PyString_FromString(outbl.to_str().c_str());
- auto pyOutS = PyString_FromString(outs.c_str());
- auto args = PyTuple_Pack(3, pyR, pyOutBl, pyOutS);
- Py_DECREF(pyR);
- Py_DECREF(pyOutBl);
- Py_DECREF(pyOutS);
-
- auto rtn = PyObject_CallObject(set_fn, args);
- if (rtn != nullptr) {
- Py_DECREF(rtn);
+ dout(10) << "MonCommandCompletion::finish()" << dendl;
+ {
+ // Scoped so the Gil is released before calling notify_all()
+ Gil gil(pThreadState);
+
+ auto set_fn = PyObject_GetAttrString(python_completion, "complete");
+ assert(set_fn != nullptr);
+
+ auto pyR = PyInt_FromLong(r);
+ auto pyOutBl = PyString_FromString(outbl.to_str().c_str());
+ auto pyOutS = PyString_FromString(outs.c_str());
+ auto args = PyTuple_Pack(3, pyR, pyOutBl, pyOutS);
+ Py_DECREF(pyR);
+ Py_DECREF(pyOutBl);
+ Py_DECREF(pyOutS);
+
+ auto rtn = PyObject_CallObject(set_fn, args);
+ if (rtn != nullptr) {
+ Py_DECREF(rtn);
+ }
+ Py_DECREF(args);
}
- Py_DECREF(args);
-
- PyGILState_Release(gstate);
-
global_handle->notify_all("command", tag);
}
};
}
Py_DECREF(set_fn);
- auto c = new MonCommandCompletion(completion, tag);
+ auto c = new MonCommandCompletion(completion, tag, PyThreadState_Get());
if (std::string(type) == "mon") {
global_handle->get_monc().start_mon_command(
{cmd_json},
std::string err;
uint64_t osd_id = strict_strtoll(name, 10, &err);
if (!err.empty()) {
- // TODO: raise exception
+ delete c;
+ string msg("invalid osd_id: ");
+ msg.append("\"").append(name).append("\"");
+ PyErr_SetString(PyExc_ValueError, msg.c_str());
return nullptr;
}
&c->outs,
c);
if (r != 0) {
- // TODO: raise exception
+ string msg("failed to send command to mds: ");
+ msg.append(cpp_strerror(r));
+ PyErr_SetString(PyExc_RuntimeError, msg.c_str());
return nullptr;
}
} else if (std::string(type) == "pg") {
// TODO: expose objecter::pg_command
return nullptr;
} else {
- // TODO: raise exception
+ string msg("unknown service type: ");
+ msg.append(type);
+ PyErr_SetString(PyExc_ValueError, msg.c_str());
return nullptr;
}
}
}
+static PyObject*
+ceph_get_mgr_id(PyObject *self, PyObject *args)
+{
+ return PyString_FromString(g_conf->name.get_id().c_str());
+}
+
static PyObject*
ceph_config_get(PyObject *self, PyObject *args)
{
std::string value;
bool found = global_handle->get_config(handle, what, &value);
if (found) {
- derr << "Found" << dendl;
+ dout(10) << "ceph_config_get " << what << " found: " << value.c_str() << dendl;
return PyString_FromString(value.c_str());
} else {
- derr << "Not found" << dendl;
+ derr << "ceph_config_get " << what << " not found " << dendl;
Py_RETURN_NONE;
}
}
+static PyObject*
+ceph_config_get_prefix(PyObject *self, PyObject *args)
+{
+ char *handle = nullptr;
+ char *prefix = nullptr;
+ if (!PyArg_ParseTuple(args, "ss:ceph_config_get", &handle, &prefix)) {
+ derr << "Invalid args!" << dendl;
+ return nullptr;
+ }
+
+ return global_handle->get_config_prefix(handle, prefix);
+}
+
static PyObject*
ceph_config_set(PyObject *self, PyObject *args)
{
"Get a service's metadata"},
{"send_command", ceph_send_command, METH_VARARGS,
"Send a mon command"},
+ {"get_mgr_id", ceph_get_mgr_id, METH_NOARGS,
+ "Get the mgr id"},
{"get_config", ceph_config_get, METH_VARARGS,
"Get a configuration value"},
+ {"get_config_prefix", ceph_config_get_prefix, METH_VARARGS,
+ "Get all configuration values with a given prefix"},
{"set_config", ceph_config_set, METH_VARARGS,
"Set a configuration value"},
{"get_counter", get_counter, METH_VARARGS,