]>
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.
21 #include "PluginRegistry.h"
23 #include "common/ceph_context.h"
24 #include "common/errno.h"
25 #include "include/str_list.h"
27 #include "common/debug.h"
29 #define PLUGIN_PREFIX "libceph_"
30 #define PLUGIN_SUFFIX ".so"
31 #define PLUGIN_INIT_FUNCTION "__ceph_plugin_init"
32 #define PLUGIN_VERSION_FUNCTION "__ceph_plugin_version"
34 #define dout_subsys ceph_subsys_context
36 PluginRegistry::PluginRegistry(CephContext
*cct
) :
38 lock("PluginRegistry::lock"),
40 disable_dlclose(false)
44 PluginRegistry::~PluginRegistry()
49 for (std::map
<std::string
,std::map
<std::string
, Plugin
*> >::iterator i
=
53 for (std::map
<std::string
,Plugin
*>::iterator j
= i
->second
.begin();
54 j
!= i
->second
.end(); ++j
) {
55 void *library
= j
->second
->library
;
62 int PluginRegistry::remove(const std::string
& type
, const std::string
& name
)
64 assert(lock
.is_locked());
66 std::map
<std::string
,std::map
<std::string
,Plugin
*> >::iterator i
=
68 if (i
== plugins
.end())
70 std::map
<std::string
,Plugin
*>::iterator j
= i
->second
.find(name
);
71 if (j
== i
->second
.end())
74 ldout(cct
, 1) << __func__
<< " " << type
<< " " << name
<< dendl
;
75 void *library
= j
->second
->library
;
79 if (i
->second
.empty())
85 int PluginRegistry::add(const std::string
& type
,
86 const std::string
& name
,
89 assert(lock
.is_locked());
90 if (plugins
.count(type
) &&
91 plugins
[type
].count(name
)) {
94 ldout(cct
, 1) << __func__
<< " " << type
<< " " << name
95 << " " << plugin
<< dendl
;
96 plugins
[type
][name
] = plugin
;
100 Plugin
*PluginRegistry::get_with_load(const std::string
& type
,
101 const std::string
& name
)
103 Mutex::Locker
l(lock
);
104 Plugin
* ret
= get(type
, name
);
106 int err
= load(type
, name
);
108 ret
= get(type
, name
);
113 Plugin
*PluginRegistry::get(const std::string
& type
,
114 const std::string
& name
)
116 assert(lock
.is_locked());
119 std::map
<std::string
,Plugin
*>::iterator j
;
120 std::map
<std::string
,map
<std::string
,Plugin
*> >::iterator i
=
122 if (i
== plugins
.end())
124 j
= i
->second
.find(name
);
125 if (j
== i
->second
.end())
130 ldout(cct
, 1) << __func__
<< " " << type
<< " " << name
131 << " = " << ret
<< dendl
;
135 int PluginRegistry::load(const std::string
&type
,
136 const std::string
&name
)
138 assert(lock
.is_locked());
139 ldout(cct
, 1) << __func__
<< " " << type
<< " " << name
<< dendl
;
141 // std::string fname = cct->_conf->plugin_dir + "/" + type + "/" PLUGIN_PREFIX
142 // + name + PLUGIN_SUFFIX;
143 std::string fname
= cct
->_conf
->get_val
<std::string
>("plugin_dir") + "/" + type
+ "/" + PLUGIN_PREFIX
144 + name
+ PLUGIN_SUFFIX
;
145 void *library
= dlopen(fname
.c_str(), RTLD_NOW
);
147 string
err1(dlerror());
148 // fall back to plugin_dir
149 std::string fname2
= cct
->_conf
->get_val
<std::string
>("plugin_dir") + "/" + PLUGIN_PREFIX
+
150 name
+ PLUGIN_SUFFIX
;
151 library
= dlopen(fname2
.c_str(), RTLD_NOW
);
153 lderr(cct
) << __func__
154 << " failed dlopen(): \"" << err1
.c_str()
155 << "\" or \"" << dlerror() << "\""
161 const char * (*code_version
)() =
162 (const char *(*)())dlsym(library
, PLUGIN_VERSION_FUNCTION
);
163 if (code_version
== NULL
) {
164 lderr(cct
) << __func__
<< " code_version == NULL" << dlerror() << dendl
;
167 if (code_version() != string(CEPH_GIT_NICE_VER
)) {
168 lderr(cct
) << __func__
<< " plugin " << fname
<< " version "
169 << code_version() << " != expected "
170 << CEPH_GIT_NICE_VER
<< dendl
;
175 int (*code_init
)(CephContext
*,
176 const std::string
& type
,
177 const std::string
& name
) =
178 (int (*)(CephContext
*,
179 const std::string
& type
,
180 const std::string
& name
))dlsym(library
, PLUGIN_INIT_FUNCTION
);
182 int r
= code_init(cct
, type
, name
);
184 lderr(cct
) << __func__
<< " " << fname
<< " "
185 << PLUGIN_INIT_FUNCTION
<< "(" << cct
186 << "," << type
<< "," << name
<< "): " << cpp_strerror(r
)
192 lderr(cct
) << __func__
<< " " << fname
<< " dlsym(" << PLUGIN_INIT_FUNCTION
193 << "): " << dlerror() << dendl
;
198 Plugin
*plugin
= get(type
, name
);
200 lderr(cct
) << __func__
<< " " << fname
<< " "
201 << PLUGIN_INIT_FUNCTION
<< "()"
202 << "did not register plugin type " << type
<< " name " << name
208 plugin
->library
= library
;
210 ldout(cct
, 1) << __func__
<< ": " << type
<< " " << name
211 << " loaded and registered" << dendl
;
216 int ErasureCodePluginRegistry::preload(const std::string &plugins,
217 const std::string &directory,
220 Mutex::Locker l(lock);
221 list<string> plugins_list;
222 get_str_list(plugins, plugins_list);
223 for (list<string>::iterator i = plugins_list.begin();
224 i != plugins_list.end();
226 ErasureCodePlugin *plugin;
227 int r = load(*i, directory, &plugin, ss);