X-Git-Url: https://gerrit.opnfv.org/gerrit/gitweb?a=blobdiff_plain;f=src%2Fceph%2Fsrc%2Fmgr%2FStandbyPyModules.cc;fp=src%2Fceph%2Fsrc%2Fmgr%2FStandbyPyModules.cc;h=0000000000000000000000000000000000000000;hb=7da45d65be36d36b880cc55c5036e96c24b53f00;hp=e567269a3c75c2dedc7d56a754c3db031544d12c;hpb=691462d09d0987b47e112d6ee8740375df3c51b2;p=stor4nfv.git diff --git a/src/ceph/src/mgr/StandbyPyModules.cc b/src/ceph/src/mgr/StandbyPyModules.cc deleted file mode 100644 index e567269..0000000 --- a/src/ceph/src/mgr/StandbyPyModules.cc +++ /dev/null @@ -1,200 +0,0 @@ -// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- -// vim: ts=8 sw=2 smarttab -/* - * Ceph - scalable distributed file system - * - * Copyright (C) 2016 John Spray - * - * This is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License version 2.1, as published by the Free Software - * Foundation. See file COPYING. - */ - -#include "StandbyPyModules.h" - -#include "common/debug.h" - -#include "mgr/MgrContext.h" -#include "mgr/Gil.h" - - -#include -#include "include/assert.h" // boost clobbers this - -// For ::config_prefix -#include "PyModuleRegistry.h" - -#define dout_context g_ceph_context -#define dout_subsys ceph_subsys_mgr -#undef dout_prefix -#define dout_prefix *_dout << "mgr " << __func__ << " " - -// Declaration fulfilled by ActivePyModules -std::string handle_pyerror(); - - -StandbyPyModules::StandbyPyModules(MonClient *monc_, const MgrMap &mgr_map_) - : monc(monc_), load_config_thread(monc, &state) -{ - state.set_mgr_map(mgr_map_); -} - -// FIXME: completely identical to ActivePyModules -void StandbyPyModules::shutdown() -{ - Mutex::Locker locker(lock); - - if (!state.is_config_loaded && load_config_thread.is_started()) { - // FIXME: handle cases where initial load races with shutdown - // this is actually not super rare because - assert(0); - //load_config_thread.kill(SIGKILL); - } - - // Signal modules to drop out of serve() and/or tear down resources - for (auto &i : modules) { - auto module = i.second.get(); - const auto& name = i.first; - dout(10) << "waiting for module " << name << " to shutdown" << dendl; - lock.Unlock(); - module->shutdown(); - lock.Lock(); - dout(10) << "module " << name << " shutdown" << dendl; - } - - // For modules implementing serve(), finish the threads where we - // were running that. - for (auto &i : modules) { - lock.Unlock(); - dout(10) << "joining thread for module " << i.first << dendl; - i.second->thread.join(); - dout(10) << "joined thread for module " << i.first << dendl; - lock.Lock(); - } - - modules.clear(); -} - -int StandbyPyModules::start_one(std::string const &module_name, - PyObject *pClass, const SafeThreadState &pMyThreadState) -{ - Mutex::Locker l(lock); - - assert(modules.count(module_name) == 0); - - modules[module_name].reset(new StandbyPyModule( - state, - module_name, pClass, - pMyThreadState)); - - if (modules.size() == 1) { - load_config_thread.create("LoadConfig"); - } - - int r = modules[module_name]->load(); - if (r != 0) { - modules.erase(module_name); - return r; - } else { - dout(4) << "Starting thread for " << module_name << dendl; - // Giving Thread the module's module_name member as its - // char* thread name: thread must not outlive module class lifetime. - modules[module_name]->thread.create( - modules[module_name]->get_name().c_str()); - return 0; - } -} - -int StandbyPyModule::load() -{ - Gil gil(pMyThreadState, true); - - // We tell the module how we name it, so that it can be consistent - // with us in logging etc. - auto pThisPtr = PyCapsule_New(this, nullptr, nullptr); - assert(pThisPtr != nullptr); - auto pModuleName = PyString_FromString(module_name.c_str()); - assert(pModuleName != nullptr); - auto pArgs = PyTuple_Pack(2, pModuleName, pThisPtr); - Py_DECREF(pThisPtr); - Py_DECREF(pModuleName); - - pClassInstance = PyObject_CallObject(pClass, pArgs); - Py_DECREF(pArgs); - if (pClassInstance == nullptr) { - derr << "Failed to construct class in '" << module_name << "'" << dendl; - derr << handle_pyerror() << dendl; - return -EINVAL; - } else { - dout(1) << "Constructed class from module: " << module_name << dendl; - return 0; - } -} - -void *StandbyPyModules::LoadConfigThread::entry() -{ - dout(10) << "listing keys" << dendl; - JSONCommand cmd; - cmd.run(monc, "{\"prefix\": \"config-key ls\"}"); - cmd.wait(); - assert(cmd.r == 0); - - std::map loaded; - - for (auto &key_str : cmd.json_result.get_array()) { - std::string const key = key_str.get_str(); - dout(20) << "saw key '" << key << "'" << dendl; - - const std::string config_prefix = PyModuleRegistry::config_prefix; - - if (key.substr(0, config_prefix.size()) == config_prefix) { - dout(20) << "fetching '" << key << "'" << dendl; - Command get_cmd; - std::ostringstream cmd_json; - cmd_json << "{\"prefix\": \"config-key get\", \"key\": \"" << key << "\"}"; - get_cmd.run(monc, cmd_json.str()); - get_cmd.wait(); - assert(get_cmd.r == 0); - loaded[key] = get_cmd.outbl.to_str(); - } - } - state->loaded_config(loaded); - - return nullptr; -} - -bool StandbyPyModule::get_config(const std::string &key, - std::string *value) const -{ - PyThreadState *tstate = PyEval_SaveThread(); - PyEval_RestoreThread(tstate); - - const std::string global_key = PyModuleRegistry::config_prefix - + module_name + "/" + key; - - dout(4) << __func__ << "key: " << global_key << dendl; - - return state.with_config([global_key, value](const PyModuleConfig &config){ - if (config.count(global_key)) { - *value = config.at(global_key); - return true; - } else { - return false; - } - }); -} - -std::string StandbyPyModule::get_active_uri() const -{ - std::string result; - state.with_mgr_map([&result, this](const MgrMap &mgr_map){ - auto iter = mgr_map.services.find(module_name); - if (iter != mgr_map.services.end()) { - result = iter->second; - } - }); - - return result; -} -