1 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2 // vim: ts=8 sw=2 smarttab
4 * Ceph distributed storage system
6 * Copyright (C) 2013,2014 Cloudwatt <libre.licensing@cloudwatt.com>
7 * Copyright (C) 2014 Red Hat <contact@redhat.com>
9 * Author: Loic Dachary <loic@dachary.org>
11 * This library is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU Lesser General Public
13 * License as published by the Free Software Foundation; either
14 * version 2.1 of the License, or (at your option) any later version.
18 #include "PluginRegistry.h"
20 #include "common/errno.h"
21 #include "common/debug.h"
25 #define PLUGIN_PREFIX "libceph_"
26 #define PLUGIN_SUFFIX ".so"
27 #define PLUGIN_INIT_FUNCTION "__ceph_plugin_init"
28 #define PLUGIN_VERSION_FUNCTION "__ceph_plugin_version"
30 #define dout_subsys ceph_subsys_context
32 PluginRegistry::PluginRegistry(CephContext *cct) :
34 lock("PluginRegistry::lock"),
36 disable_dlclose(false)
40 PluginRegistry::~PluginRegistry()
45 for (std::map<std::string,std::map<std::string, Plugin*> >::iterator i =
49 for (std::map<std::string,Plugin*>::iterator j = i->second.begin();
50 j != i->second.end(); ++j) {
51 void *library = j->second->library;
58 int PluginRegistry::remove(const std::string& type, const std::string& name)
60 assert(lock.is_locked());
62 std::map<std::string,std::map<std::string,Plugin*> >::iterator i =
64 if (i == plugins.end())
66 std::map<std::string,Plugin*>::iterator j = i->second.find(name);
67 if (j == i->second.end())
70 ldout(cct, 1) << __func__ << " " << type << " " << name << dendl;
71 void *library = j->second->library;
75 if (i->second.empty())
81 int PluginRegistry::add(const std::string& type,
82 const std::string& name,
85 assert(lock.is_locked());
86 if (plugins.count(type) &&
87 plugins[type].count(name)) {
90 ldout(cct, 1) << __func__ << " " << type << " " << name
91 << " " << plugin << dendl;
92 plugins[type][name] = plugin;
96 Plugin *PluginRegistry::get_with_load(const std::string& type,
97 const std::string& name)
99 Mutex::Locker l(lock);
100 Plugin* ret = get(type, name);
102 int err = load(type, name);
104 ret = get(type, name);
109 Plugin *PluginRegistry::get(const std::string& type,
110 const std::string& name)
112 assert(lock.is_locked());
115 std::map<std::string,Plugin*>::iterator j;
116 std::map<std::string,map<std::string,Plugin*> >::iterator i =
118 if (i == plugins.end())
120 j = i->second.find(name);
121 if (j == i->second.end())
126 ldout(cct, 1) << __func__ << " " << type << " " << name
127 << " = " << ret << dendl;
131 int PluginRegistry::load(const std::string &type,
132 const std::string &name)
134 assert(lock.is_locked());
135 ldout(cct, 1) << __func__ << " " << type << " " << name << dendl;
137 // std::string fname = cct->_conf->plugin_dir + "/" + type + "/" PLUGIN_PREFIX
138 // + name + PLUGIN_SUFFIX;
139 std::string fname = cct->_conf->get_val<std::string>("plugin_dir") + "/" + type + "/" + PLUGIN_PREFIX
140 + name + PLUGIN_SUFFIX;
141 void *library = dlopen(fname.c_str(), RTLD_NOW);
143 string err1(dlerror());
144 // fall back to plugin_dir
145 std::string fname2 = cct->_conf->get_val<std::string>("plugin_dir") + "/" + PLUGIN_PREFIX +
146 name + PLUGIN_SUFFIX;
147 library = dlopen(fname2.c_str(), RTLD_NOW);
149 lderr(cct) << __func__
150 << " failed dlopen(): \"" << err1.c_str()
151 << "\" or \"" << dlerror() << "\""
157 const char * (*code_version)() =
158 (const char *(*)())dlsym(library, PLUGIN_VERSION_FUNCTION);
159 if (code_version == NULL) {
160 lderr(cct) << __func__ << " code_version == NULL" << dlerror() << dendl;
163 if (code_version() != string(CEPH_GIT_NICE_VER)) {
164 lderr(cct) << __func__ << " plugin " << fname << " version "
165 << code_version() << " != expected "
166 << CEPH_GIT_NICE_VER << dendl;
171 int (*code_init)(CephContext *,
172 const std::string& type,
173 const std::string& name) =
174 (int (*)(CephContext *,
175 const std::string& type,
176 const std::string& name))dlsym(library, PLUGIN_INIT_FUNCTION);
178 int r = code_init(cct, type, name);
180 lderr(cct) << __func__ << " " << fname << " "
181 << PLUGIN_INIT_FUNCTION << "(" << cct
182 << "," << type << "," << name << "): " << cpp_strerror(r)
188 lderr(cct) << __func__ << " " << fname << " dlsym(" << PLUGIN_INIT_FUNCTION
189 << "): " << dlerror() << dendl;
194 Plugin *plugin = get(type, name);
196 lderr(cct) << __func__ << " " << fname << " "
197 << PLUGIN_INIT_FUNCTION << "()"
198 << "did not register plugin type " << type << " name " << name
204 plugin->library = library;
206 ldout(cct, 1) << __func__ << ": " << type << " " << name
207 << " loaded and registered" << dendl;
212 int ErasureCodePluginRegistry::preload(const std::string &plugins,
213 const std::string &directory,
216 Mutex::Locker l(lock);
217 list<string> plugins_list;
218 get_str_list(plugins, plugins_list);
219 for (list<string>::iterator i = plugins_list.begin();
220 i != plugins_list.end();
222 ErasureCodePlugin *plugin;
223 int r = load(*i, directory, &plugin, ss);