From 46003075924bb16b41149e7c12f31e9a6b7a3f15 Mon Sep 17 00:00:00 2001 From: Kefu Chai Date: Wed, 24 Jan 2018 01:13:50 +0800 Subject: [PATCH] mgr: be compatible with py3 so ceph-mgr can be compiled using py3 Signed-off-by: Kefu Chai --- src/mgr/BaseMgrStandbyModule.h | 2 +- src/mgr/Mgr.h | 8 +----- src/mgr/PyFormatter.h | 8 +----- src/mgr/PyModule.cc | 50 +++++++++++++++++++++++++++++----- src/mgr/PyModuleRegistry.cc | 9 ++++-- src/mgr/PyModuleRunner.cc | 2 +- src/mgr/PyOSDMap.h | 2 +- src/mgr/PythonCompat.h | 28 +++++++++++++++++++ src/mgr/StandbyPyModules.h | 2 +- 9 files changed, 83 insertions(+), 28 deletions(-) create mode 100644 src/mgr/PythonCompat.h diff --git a/src/mgr/BaseMgrStandbyModule.h b/src/mgr/BaseMgrStandbyModule.h index c5c6beb1d3c..c4cf267304c 100644 --- a/src/mgr/BaseMgrStandbyModule.h +++ b/src/mgr/BaseMgrStandbyModule.h @@ -1,7 +1,7 @@ #pragma once -#include "Python.h" +#include "PythonCompat.h" extern PyTypeObject BaseMgrStandbyModuleType; diff --git a/src/mgr/Mgr.h b/src/mgr/Mgr.h index 912114c380b..173fe04a1d5 100644 --- a/src/mgr/Mgr.h +++ b/src/mgr/Mgr.h @@ -15,13 +15,7 @@ #define CEPH_MGR_H_ // Python.h comes first because otherwise it clobbers ceph's assert -#include "Python.h" -// Python's pyconfig-64.h conflicts with ceph's acconfig.h -#undef HAVE_SYS_WAIT_H -#undef HAVE_UNISTD_H -#undef HAVE_UTIME_H -#undef _POSIX_C_SOURCE -#undef _XOPEN_SOURCE +#include "PythonCompat.h" #include "mds/FSMap.h" #include "messages/MFSMap.h" diff --git a/src/mgr/PyFormatter.h b/src/mgr/PyFormatter.h index ec4dad81c29..e74f2fe7c49 100644 --- a/src/mgr/PyFormatter.h +++ b/src/mgr/PyFormatter.h @@ -18,13 +18,7 @@ #define PY_FORMATTER_H_ // Python.h comes first because otherwise it clobbers ceph's assert -#include "Python.h" -// Python's pyconfig-64.h conflicts with ceph's acconfig.h -#undef HAVE_SYS_WAIT_H -#undef HAVE_UNISTD_H -#undef HAVE_UTIME_H -#undef _POSIX_C_SOURCE -#undef _XOPEN_SOURCE +#include "PythonCompat.h" #include #include diff --git a/src/mgr/PyModule.cc b/src/mgr/PyModule.cc index d2d825ca0d5..f3fede8de6e 100644 --- a/src/mgr/PyModule.cc +++ b/src/mgr/PyModule.cc @@ -72,6 +72,16 @@ namespace { {"flush", log_flush, METH_VARARGS, "flush"}, {nullptr, nullptr, 0, nullptr} }; + +#if PY_MAJOR_VERSION >= 3 + static PyModuleDef ceph_logger_module = { + PyModuleDef_HEAD_INIT, + "ceph_logger", + nullptr, + -1, + log_methods, + }; +#endif } @@ -159,34 +169,60 @@ int PyModule::load(PyThreadState *pMainThreadState) pMyThreadState.set(thread_state); // Some python modules do not cope with an unpopulated argv, so lets // fake one. This step also picks up site-packages into sys.path. +#if PY_MAJOR_VERSION >= 3 + const wchar_t *argv[] = {L"ceph-mgr"}; + PySys_SetArgv(1, (wchar_t**)argv); +#else const char *argv[] = {"ceph-mgr"}; PySys_SetArgv(1, (char**)argv); +#endif if (g_conf->daemonize) { - auto py_logger = Py_InitModule("ceph_logger", log_methods); #if PY_MAJOR_VERSION >= 3 + auto py_logger = PyModule_Create(&ceph_logger_module); PySys_SetObject("stderr", py_logger); PySys_SetObject("stdout", py_logger); #else + auto py_logger = Py_InitModule("ceph_logger", log_methods); PySys_SetObject(const_cast("stderr"), py_logger); PySys_SetObject(const_cast("stdout"), py_logger); #endif } // Configure sys.path to include mgr_module_path - std::string sys_path = std::string(Py_GetPath()) + ":" + get_site_packages() - + ":" + g_conf->get_val("mgr_module_path"); - dout(10) << "Computed sys.path '" << sys_path << "'" << dendl; - + string paths = (":" + get_site_packages() + + ":" + g_conf->get_val("mgr_module_path")); +#if PY_MAJOR_VERSION >= 3 + wstring sys_path(Py_GetPath() + wstring(begin(paths), end(paths))); + PySys_SetPath(const_cast(sys_path.c_str())); + dout(10) << "Computed sys.path '" + << string(begin(sys_path), end(sys_path)) << "'" << dendl; +#else + string sys_path(Py_GetPath() + paths); PySys_SetPath(const_cast(sys_path.c_str())); + dout(10) << "Computed sys.path '" << sys_path << "'" << dendl; +#endif } - PyMethodDef ModuleMethods[] = { + static PyMethodDef module_methods[] = { {nullptr} }; +#if PY_MAJOR_VERSION >= 3 + static PyModuleDef ceph_module_def = { + PyModuleDef_HEAD_INIT, + "ceph_module", + nullptr, + -1, + module_methods, + }; +#endif // Initialize module - PyObject *ceph_module = Py_InitModule("ceph_module", ModuleMethods); +#if PY_MAJOR_VERSION >= 3 + PyObject *ceph_module = PyModule_Create(&ceph_module_def); +#else + PyObject *ceph_module = Py_InitModule("ceph_module", module_methods); +#endif assert(ceph_module != nullptr); auto load_class = [ceph_module](const char *name, PyTypeObject *type) diff --git a/src/mgr/PyModuleRegistry.cc b/src/mgr/PyModuleRegistry.cc index 76ad1577075..867814bfa16 100644 --- a/src/mgr/PyModuleRegistry.cc +++ b/src/mgr/PyModuleRegistry.cc @@ -37,9 +37,6 @@ std::string PyModuleRegistry::config_prefix; -#undef dout_prefix -#define dout_prefix *_dout << "mgr " << __func__ << " " - int PyModuleRegistry::init(const MgrMap &map) { Mutex::Locker locker(lock); @@ -53,7 +50,13 @@ int PyModuleRegistry::init(const MgrMap &map) config_prefix = std::string(g_conf->name.get_type_str()) + "/"; // Set up global python interpreter +#if PY_MAJOR_VERSION >= 3 +#define WCHAR(s) L ## #s + Py_SetProgramName(const_cast(WCHAR(PYTHON_EXECUTABLE))); +#undef WCHAR +#else Py_SetProgramName(const_cast(PYTHON_EXECUTABLE)); +#endif Py_InitializeEx(0); // Let CPython know that we will be calling it back from other diff --git a/src/mgr/PyModuleRunner.cc b/src/mgr/PyModuleRunner.cc index 81d74473504..5b98a70279a 100644 --- a/src/mgr/PyModuleRunner.cc +++ b/src/mgr/PyModuleRunner.cc @@ -13,7 +13,7 @@ // Python.h comes first because otherwise it clobbers ceph's assert -#include "Python.h" +#include "PythonCompat.h" #include "PyModule.h" diff --git a/src/mgr/PyOSDMap.h b/src/mgr/PyOSDMap.h index 09e5b041c87..9d737424913 100644 --- a/src/mgr/PyOSDMap.h +++ b/src/mgr/PyOSDMap.h @@ -5,7 +5,7 @@ #include -#include "Python.h" +#include "PythonCompat.h" diff --git a/src/mgr/PythonCompat.h b/src/mgr/PythonCompat.h new file mode 100644 index 00000000000..745dad1a7e7 --- /dev/null +++ b/src/mgr/PythonCompat.h @@ -0,0 +1,28 @@ +#pragma once + +#include + +// Python's pyconfig-64.h conflicts with ceph's acconfig.h +#undef HAVE_SYS_WAIT_H +#undef HAVE_UNISTD_H +#undef HAVE_UTIME_H +#undef _POSIX_C_SOURCE +#undef _XOPEN_SOURCE + +#if PY_MAJOR_VERSION >= 3 +inline PyObject* PyString_FromString(const char *v) { + return PyUnicode_FromFormat("%s", v); +} +inline char* PyString_AsString(PyObject *string) { + return PyUnicode_AsUTF8(string); +} +inline long PyInt_AsLong(PyObject *io) { + return PyLong_AsLong(io); +} +inline PyObject* PyInt_FromLong(long ival) { + return PyLong_FromLong(ival); +} +inline int PyString_Check(PyObject *o) { + return PyUnicode_Check(o); +} +#endif diff --git a/src/mgr/StandbyPyModules.h b/src/mgr/StandbyPyModules.h index a22887bdeae..14d968ec3b3 100644 --- a/src/mgr/StandbyPyModules.h +++ b/src/mgr/StandbyPyModules.h @@ -13,7 +13,7 @@ #pragma once -#include "Python.h" +#include "PythonCompat.h" #include #include -- 2.39.5