summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKefu Chai <kchai@redhat.com>2021-03-27 17:56:39 +0100
committerKefu Chai <kchai@redhat.com>2021-04-01 09:46:22 +0200
commit2d3c6561b4ac1473a728e81c232d7dfe6fc0188c (patch)
treefdb3185ad7bfbf0fe386bb918dd6d3efb1e3bbd9
parentMerge pull request #40519 from rhcs-dashboard/50077-vstart-runner-max-require... (diff)
downloadceph-2d3c6561b4ac1473a728e81c232d7dfe6fc0188c.tar.xz
ceph-2d3c6561b4ac1473a728e81c232d7dfe6fc0188c.zip
tools/ceph-dencoder: build dencoders as plugins
to reduce the memory footprint when linking ceph-dencoder. * src/tools/ceph-dencoder: * build dencoders as shared libraries named with the prefix of "den-mod-". so ceph-dencoder can find them * install dencoders into $prefix/lib/ceph/denc, so ceph-dencoder can find them * only expose "register_dencoders()" function from plugins. * load plugins in specified directory * ceph.spec.in: package plugins * debian: package plugins Signed-off-by: Kefu Chai <kchai@redhat.com>
-rw-r--r--ceph.spec.in1
-rwxr-xr-xdebian/ceph-common.install1
-rw-r--r--src/CMakeLists.txt1
-rw-r--r--src/test/CMakeLists.txt1
-rw-r--r--src/tools/ceph-dencoder/CMakeLists.txt78
-rw-r--r--src/tools/ceph-dencoder/ceph_dencoder.cc82
-rw-r--r--src/tools/ceph-dencoder/common_types.cc2
-rw-r--r--src/tools/ceph-dencoder/denc_registry.h6
-rw-r--r--src/tools/ceph-dencoder/mds_types.cc2
-rw-r--r--src/tools/ceph-dencoder/osd_types.cc2
-rw-r--r--src/tools/ceph-dencoder/rbd_types.cc2
-rw-r--r--src/tools/ceph-dencoder/rgw_types.cc2
12 files changed, 137 insertions, 43 deletions
diff --git a/ceph.spec.in b/ceph.spec.in
index 94ff292ecce..08000289c70 100644
--- a/ceph.spec.in
+++ b/ceph.spec.in
@@ -1591,6 +1591,7 @@ exit 0
%{_bindir}/rbd-replay-prep
%endif
%{_bindir}/ceph-post-file
+%{_libdir}/ceph/denc/denc-mod-*.so
%{_tmpfilesdir}/ceph-common.conf
%{_mandir}/man8/ceph-authtool.8*
%{_mandir}/man8/ceph-conf.8*
diff --git a/debian/ceph-common.install b/debian/ceph-common.install
index b84a3164d3e..b1c5769fd53 100755
--- a/debian/ceph-common.install
+++ b/debian/ceph-common.install
@@ -23,6 +23,7 @@ usr/bin/rbd-replay*
usr/bin/ceph-post-file
usr/sbin/mount.ceph sbin
usr/lib/ceph/compressor/*
+usr/lib/ceph/denc/*
usr/lib/ceph/crypto/* [amd64]
usr/share/man/man8/ceph-authtool.8
usr/share/man/man8/ceph-conf.8
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index b12e6036715..88d2d0eb550 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -954,6 +954,7 @@ add_custom_target(cephfs_testing DEPENDS
cls_cephfs
ceph-fuse
ceph-dencoder
+ ceph-dencoder-modules
cephfs-journal-tool
cephfs-meta-injection
cephfs-data-scan
diff --git a/src/test/CMakeLists.txt b/src/test/CMakeLists.txt
index 3c7625d93eb..da487ca6f2a 100644
--- a/src/test/CMakeLists.txt
+++ b/src/test/CMakeLists.txt
@@ -531,6 +531,7 @@ if(NOT WIN32)
ceph-mon
get_command_descriptions
ceph-dencoder
+ ceph-dencoder-modules
ceph-objectstore-tool
ceph-kvstore-tool
ceph-monstore-tool
diff --git a/src/tools/ceph-dencoder/CMakeLists.txt b/src/tools/ceph-dencoder/CMakeLists.txt
index 869904ebb40..dd5541cd93e 100644
--- a/src/tools/ceph-dencoder/CMakeLists.txt
+++ b/src/tools/ceph-dencoder/CMakeLists.txt
@@ -11,67 +11,93 @@ endif()
set(dencoder_srcs
denc_registry.cc
ceph_dencoder.cc
- common_types.cc
- mds_types.cc
- osd_types.cc
- rbd_types.cc
- rgw_types.cc
../../include/uuid.cc
../../include/utime.cc
$<TARGET_OBJECTS:common_texttable_obj>)
-if(WITH_RADOSGW)
- list(APPEND dencoder_srcs
- ${CMAKE_SOURCE_DIR}/src/rgw/rgw_dencoder.cc)
-endif()
-
add_executable(ceph-dencoder ${dencoder_srcs})
+set(denc_plugin_dir ${CEPH_INSTALL_PKGLIBDIR}/denc)
+add_custom_target(ceph-dencoder-modules)
+
+function(add_denc_mod name)
+ add_library(${name} SHARED
+ ${ARGN})
+ set_target_properties(${name} PROPERTIES
+ PREFIX ""
+ OUTPUT_NAME ${name}
+ CXX_VISIBILITY_PRESET hidden
+ VISIBILITY_INLINES_HIDDEN ON)
+ install(
+ TARGETS ${name}
+ DESTINATION ${denc_plugin_dir})
+ add_dependencies(ceph-dencoder-modules
+ ${name})
+endfunction()
+
+add_denc_mod(denc-mod-common
+ common_types.cc)
+target_link_libraries(denc-mod-common
+ journal
+ cls_cas_internal
+ cls_lock_client
+ cls_refcount_client
+ cls_timeindex_client)
+add_denc_mod(denc-mod-osd
+ osd_types.cc)
+target_link_libraries(denc-mod-osd
+ os
+ osd
+ mon)
+
if(WITH_RADOSGW)
- list(APPEND DENCODER_EXTRALIBS
+ add_denc_mod(denc-mod-rgw
+ rgw_types.cc
+ ${CMAKE_SOURCE_DIR}/src/rgw/rgw_dencoder.cc)
+ target_link_libraries(denc-mod-rgw
rgw_a
- cls_rgw_client)
+ cls_rgw_client
+ cls_journal_client)
if(WITH_RADOSGW_AMQP_ENDPOINT)
- list(APPEND DENCODER_EXTRALIBS
+ target_link_libraries(denc-mod-rgw
rabbitmq ssl)
endif()
if(WITH_RADOSGW_KAFKA_ENDPOINT)
- list(APPEND DENCODER_EXTRALIBS
+ target_link_libraries(denc-mod-rgw
rdkafka)
endif()
endif()
if(WITH_RBD)
- list(APPEND DENCODER_EXTRALIBS
+ add_denc_mod(denc-mod-rbd
+ rbd_types.cc)
+ target_link_libraries(denc-mod-rbd
cls_rbd_client
rbd_mirror_types
rbd_types
rbd_replay_types)
if(WITH_KRBD)
- list(APPEND DENCODER_EXTRALIBS
+ target_link_libraries(denc-mod-rbd
krbd)
endif()
endif()
if(WITH_CEPHFS)
- list(APPEND DENCODER_EXTRALIBS
+ add_denc_mod(denc-mod-cephfs
+ mds_types.cc)
+ target_link_libraries(denc-mod-cephfs
mds)
endif()
+target_compile_definitions(ceph-dencoder PRIVATE
+ "CEPH_DENC_MOD_DIR=\"${denc_plugin_dir}\"")
+
target_link_libraries(ceph-dencoder
+ StdFilesystem::filesystem
global
- os
- osd
- mon
- journal
${DENCODER_EXTRALIBS}
- cls_lock_client
- cls_refcount_client
cls_log_client
cls_version_client
cls_user_client
- cls_journal_client
- cls_timeindex_client
- cls_cas_internal
cls_cas_client
${EXTRALIBS}
${CMAKE_DL_LIBS})
diff --git a/src/tools/ceph-dencoder/ceph_dencoder.cc b/src/tools/ceph-dencoder/ceph_dencoder.cc
index 87091561b39..2bb73db0854 100644
--- a/src/tools/ceph-dencoder/ceph_dencoder.cc
+++ b/src/tools/ceph-dencoder/ceph_dencoder.cc
@@ -13,7 +13,17 @@
*/
+#include <dlfcn.h>
#include <errno.h>
+
+#if __has_include(<filesystem>)
+#include <filesystem>
+namespace fs = std::filesystem;
+#else
+#include <experimental/filesystem>
+namespace fs = std::experimental::filesystem;
+#endif
+
#include "ceph_ver.h"
#include "include/types.h"
#include "common/Formatter.h"
@@ -52,15 +62,73 @@ void usage(ostream &out)
out << " select_test <n> select generated test object as in-memory object\n";
out << " is_deterministic exit w/ success if type encodes deterministically\n";
}
-
-int main(int argc, const char **argv)
+
+static constexpr string_view REGISTER_DENCODERS_FUNCTION = "register_dencoders\0";
+
+class DencoderPlugin {
+public:
+ DencoderPlugin(const fs::path& path) {
+ mod = dlopen(path.c_str(), RTLD_NOW);
+ if (mod == nullptr) {
+ std::cerr << "failed to dlopen(" << path << "): " << dlerror() << std::endl;
+ }
+ }
+ ~DencoderPlugin() {
+ if (mod) {
+ dlclose(mod);
+ }
+ }
+ int register_dencoders() {
+ assert(mod);
+ using register_dencoders_t = void (*)();
+ const auto register_dencoders =
+ reinterpret_cast<register_dencoders_t>(dlsym(mod, REGISTER_DENCODERS_FUNCTION.data()));
+ if (register_dencoders == nullptr) {
+ std::cerr << "failed to dlsym(" << REGISTER_DENCODERS_FUNCTION << ")" << std::endl;
+ return -1;
+ }
+ const unsigned nr_before = DencoderRegistry::instance().get().size();
+ register_dencoders();
+ const unsigned nr_after = DencoderRegistry::instance().get().size();
+ return nr_after - nr_before;
+ }
+ bool good() const {
+ return mod != nullptr;
+ }
+private:
+ void *mod = nullptr;
+};
+
+vector<DencoderPlugin> load_plugins()
{
- register_common_dencoders();
- register_mds_dencoders();
- register_osd_dencoders();
- register_rbd_dencoders();
- register_rgw_dencoders();
+ fs::path mod_dir{CEPH_DENC_MOD_DIR};
+ if (auto ceph_lib = getenv("CEPH_LIB"); ceph_lib) {
+ mod_dir = ceph_lib;
+ }
+ vector<DencoderPlugin> dencoder_plugins;
+ for (auto& entry : fs::directory_iterator(mod_dir)) {
+ static const string_view DENC_MOD_PREFIX = "denc-mod-";
+ if (entry.path().stem().string().compare(0, DENC_MOD_PREFIX.size(),
+ DENC_MOD_PREFIX) != 0) {
+ continue;
+ }
+ DencoderPlugin plugin(entry);
+ if (!plugin.good()) {
+ continue;
+ }
+ int n = plugin.register_dencoders();
+ if (n <= 0) {
+ std::cerr << "fail to load dencoders from " << entry << std::endl;
+ continue;
+ }
+ dencoder_plugins.push_back(std::move(plugin));
+ }
+ return dencoder_plugins;
+}
+int main(int argc, const char **argv)
+{
+ auto plugins = load_plugins();
auto& dencoders = DencoderRegistry::instance().get();
vector<const char*> args;
diff --git a/src/tools/ceph-dencoder/common_types.cc b/src/tools/ceph-dencoder/common_types.cc
index 889a9e99e1c..86c08c51211 100644
--- a/src/tools/ceph-dencoder/common_types.cc
+++ b/src/tools/ceph-dencoder/common_types.cc
@@ -25,7 +25,7 @@ using namespace std;
#include "denc_registry.h"
-void register_common_dencoders()
+DENC_API void register_dencoders()
{
#include "common_types.h"
}
diff --git a/src/tools/ceph-dencoder/denc_registry.h b/src/tools/ceph-dencoder/denc_registry.h
index 74c7be97db7..a5bc2b261df 100644
--- a/src/tools/ceph-dencoder/denc_registry.h
+++ b/src/tools/ceph-dencoder/denc_registry.h
@@ -253,8 +253,4 @@ void make_and_register_dencoder(const char* name, Args&&...args)
#define TYPE_NOCOPY(t) make_and_register_dencoder<DencoderImplNoFeatureNoCopy<t>>(#t, false, false);
#define MESSAGE(t) make_and_register_dencoder<MessageDencoderImpl<t>>(#t);
-void register_common_dencoders();
-void register_mds_dencoders();
-void register_osd_dencoders();
-void register_rbd_dencoders();
-void register_rgw_dencoders();
+#define DENC_API extern "C" [[gnu::visibility("default")]]
diff --git a/src/tools/ceph-dencoder/mds_types.cc b/src/tools/ceph-dencoder/mds_types.cc
index 5bec4bb146c..d28306cbf6b 100644
--- a/src/tools/ceph-dencoder/mds_types.cc
+++ b/src/tools/ceph-dencoder/mds_types.cc
@@ -25,7 +25,7 @@ using namespace std;
#include "denc_registry.h"
-void register_mds_dencoders()
+DENC_API void register_dencoders()
{
#include "mds_types.h"
}
diff --git a/src/tools/ceph-dencoder/osd_types.cc b/src/tools/ceph-dencoder/osd_types.cc
index c0b82d4f36b..d21e904b9cc 100644
--- a/src/tools/ceph-dencoder/osd_types.cc
+++ b/src/tools/ceph-dencoder/osd_types.cc
@@ -28,7 +28,7 @@ using namespace std;
// cannot initialize dencoders when initializing static variables, as some of
// the types are allocated using mempool, and the mempools are initialized as
// static variables.
-void register_osd_dencoders()
+DENC_API void register_dencoders()
{
#include "osd_types.h"
}
diff --git a/src/tools/ceph-dencoder/rbd_types.cc b/src/tools/ceph-dencoder/rbd_types.cc
index 6327d1904a1..a9ffe74aea5 100644
--- a/src/tools/ceph-dencoder/rbd_types.cc
+++ b/src/tools/ceph-dencoder/rbd_types.cc
@@ -25,7 +25,7 @@ using namespace std;
#include "denc_registry.h"
-void register_rbd_dencoders()
+DENC_API void register_dencoders()
{
#include "rbd_types.h"
}
diff --git a/src/tools/ceph-dencoder/rgw_types.cc b/src/tools/ceph-dencoder/rgw_types.cc
index 82dde00d24e..de557cda54d 100644
--- a/src/tools/ceph-dencoder/rgw_types.cc
+++ b/src/tools/ceph-dencoder/rgw_types.cc
@@ -25,7 +25,7 @@ using namespace std;
#include "denc_registry.h"
-void register_rgw_dencoders()
+DENC_API void register_dencoders()
{
#include "rgw_types.h"
}