diff options
author | Kefu Chai <kchai@redhat.com> | 2021-03-27 17:56:39 +0100 |
---|---|---|
committer | Kefu Chai <kchai@redhat.com> | 2021-04-01 09:46:22 +0200 |
commit | 2d3c6561b4ac1473a728e81c232d7dfe6fc0188c (patch) | |
tree | fdb3185ad7bfbf0fe386bb918dd6d3efb1e3bbd9 | |
parent | Merge pull request #40519 from rhcs-dashboard/50077-vstart-runner-max-require... (diff) | |
download | ceph-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.in | 1 | ||||
-rwxr-xr-x | debian/ceph-common.install | 1 | ||||
-rw-r--r-- | src/CMakeLists.txt | 1 | ||||
-rw-r--r-- | src/test/CMakeLists.txt | 1 | ||||
-rw-r--r-- | src/tools/ceph-dencoder/CMakeLists.txt | 78 | ||||
-rw-r--r-- | src/tools/ceph-dencoder/ceph_dencoder.cc | 82 | ||||
-rw-r--r-- | src/tools/ceph-dencoder/common_types.cc | 2 | ||||
-rw-r--r-- | src/tools/ceph-dencoder/denc_registry.h | 6 | ||||
-rw-r--r-- | src/tools/ceph-dencoder/mds_types.cc | 2 | ||||
-rw-r--r-- | src/tools/ceph-dencoder/osd_types.cc | 2 | ||||
-rw-r--r-- | src/tools/ceph-dencoder/rbd_types.cc | 2 | ||||
-rw-r--r-- | src/tools/ceph-dencoder/rgw_types.cc | 2 |
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" } |