]>
git.proxmox.com Git - ceph.git/blob - ceph/src/common/PluginRegistry.cc
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);