]>
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/ceph_context.h"
21 #include "common/errno.h"
22 #include "common/debug.h"
23 #include "include/dlfcn_compat.h"
25 #define PLUGIN_PREFIX "libceph_"
26 #define PLUGIN_SUFFIX SHARED_LIB_SUFFIX
27 #define PLUGIN_INIT_FUNCTION "__ceph_plugin_init"
28 #define PLUGIN_VERSION_FUNCTION "__ceph_plugin_version"
30 #define dout_subsys ceph_subsys_context
37 PluginRegistry::PluginRegistry(CephContext
*cct
) :
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 ceph_assert(ceph_mutex_is_locked(lock
));
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 ceph_assert(ceph_mutex_is_locked(lock
));
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 std::lock_guard
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 ceph_assert(ceph_mutex_is_locked(lock
));
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 ceph_assert(ceph_mutex_is_locked(lock
));
139 ldout(cct
, 1) << __func__
<< " " << type
<< " " << name
<< dendl
;
141 std::string fname
= cct
->_conf
.get_val
<std::string
>("plugin_dir") + "/" + type
+ "/" + PLUGIN_PREFIX
142 + name
+ PLUGIN_SUFFIX
;
143 void *library
= dlopen(fname
.c_str(), RTLD_NOW
);
145 string
err1(dlerror());
146 // fall back to plugin_dir
147 fname
= cct
->_conf
.get_val
<std::string
>("plugin_dir") + "/" + PLUGIN_PREFIX
+
148 name
+ PLUGIN_SUFFIX
;
149 library
= dlopen(fname
.c_str(), RTLD_NOW
);
151 lderr(cct
) << __func__
152 << " failed dlopen(): \"" << err1
.c_str()
153 << "\" or \"" << dlerror() << "\""
159 const char * (*code_version
)() =
160 (const char *(*)())dlsym(library
, PLUGIN_VERSION_FUNCTION
);
161 if (code_version
== NULL
) {
162 lderr(cct
) << __func__
<< " code_version == NULL" << dlerror() << dendl
;
165 if (code_version() != string(CEPH_GIT_NICE_VER
)) {
166 lderr(cct
) << __func__
<< " plugin " << fname
<< " version "
167 << code_version() << " != expected "
168 << CEPH_GIT_NICE_VER
<< dendl
;
173 int (*code_init
)(CephContext
*,
174 const std::string
& type
,
175 const std::string
& name
) =
176 (int (*)(CephContext
*,
177 const std::string
& type
,
178 const std::string
& name
))dlsym(library
, PLUGIN_INIT_FUNCTION
);
180 int r
= code_init(cct
, type
, name
);
182 lderr(cct
) << __func__
<< " " << fname
<< " "
183 << PLUGIN_INIT_FUNCTION
<< "(" << cct
184 << "," << type
<< "," << name
<< "): " << cpp_strerror(r
)
190 lderr(cct
) << __func__
<< " " << fname
<< " dlsym(" << PLUGIN_INIT_FUNCTION
191 << "): " << dlerror() << dendl
;
196 Plugin
*plugin
= get(type
, name
);
198 lderr(cct
) << __func__
<< " " << fname
<< " "
199 << PLUGIN_INIT_FUNCTION
<< "()"
200 << "did not register plugin type " << type
<< " name " << name
206 plugin
->library
= library
;
208 ldout(cct
, 1) << __func__
<< ": " << type
<< " " << name
209 << " loaded and registered" << dendl
;
215 int ErasureCodePluginRegistry::preload(const std::string &plugins,
216 const std::string &directory,
219 std::lock_guard l(lock);
220 list<string> plugins_list;
221 get_str_list(plugins, plugins_list);
222 for (list<string>::iterator i = plugins_list.begin();
223 i != plugins_list.end();
225 ErasureCodePlugin *plugin;
226 int r = load(*i, directory, &plugin, ss);