From: Sage Weil Date: Fri, 22 Nov 2019 15:24:11 +0000 (-0600) Subject: Revert "Merge pull request #16715 from adamemerson/wip-I-Object!" X-Git-Tag: v15.1.0~793^2 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=refs%2Fpull%2F31790%2Fhead;p=ceph.git Revert "Merge pull request #16715 from adamemerson/wip-I-Object!" This reverts commit 669453138d89e0f797a1bd37f38a2d68e6aac366, reversing changes made to 36f5fcbb97eb2b1bceb526331eb3464f460fc701. Signed-off-by: Sage Weil - conflicts due to code rearrangement in 14b0db908f652032c358e419ffa90f5676698d0e --- diff --git a/.gitignore b/.gitignore index 2600c2c614e5e..a04d59a632edc 100644 --- a/.gitignore +++ b/.gitignore @@ -73,6 +73,3 @@ GTAGS /src/pybind/mgr/dashboard/frontend/src/environments/environment.ts /src/pybind/mgr/dashboard/frontend/src/environments/environment.prod.ts /src/pybind/mgr/dashboard/frontend/src/locale/messages.xlf - -# Python building things where it shouldn't -/src/python-common/build/ diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index ca1631c2e202e..5b89d03937450 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -297,7 +297,6 @@ if(NOT fmt_FOUND) message(STATUS "Could not find fmt, will build it") add_subdirectory(fmt) endif() -include_directories(SYSTEM "${CMAKE_SOURCE_DIR}/src/fmt/include") if(WITH_SEASTAR) find_package(c-ares 1.13.0 QUIET) @@ -332,13 +331,11 @@ set(libcommon_files ${CMAKE_BINARY_DIR}/src/include/ceph_ver.h ceph_ver.c xxHash/xxhash.c - common/error_code.cc log/Log.cc mon/MonCap.cc mon/MonClient.cc mon/MonMap.cc mon/MonSub.cc - mon/error_code.cc mgr/MgrClient.cc mon/PGMap.cc mgr/ServiceMap.cc @@ -347,12 +344,10 @@ set(libcommon_files osd/OSDMap.cc osd/OSDMapMapping.cc osd/osd_types.cc - osd/error_code.cc osd/PGPeeringEvent.cc osd/OpRequest.cc osdc/Striper.cc osdc/Objecter.cc - osdc/error_code.cc librbd/Features.cc ${mds_files}) set_source_files_properties(ceph_ver.c @@ -480,7 +475,6 @@ option(WITH_LIBRADOSSTRIPER "build with libradosstriper support" ON) add_subdirectory(include) add_subdirectory(librados) -add_subdirectory(RADOS) if(WITH_LIBRADOSSTRIPER) add_subdirectory(libradosstriper) diff --git a/src/RADOS/CMakeLists.txt b/src/RADOS/CMakeLists.txt deleted file mode 100644 index c8d4f1bb2e092..0000000000000 --- a/src/RADOS/CMakeLists.txt +++ /dev/null @@ -1,37 +0,0 @@ -add_library(RADOS_objs OBJECT - RADOSImpl.cc) -add_library(RADOS_api_obj OBJECT - RADOS.cc) - -add_library(libRADOS STATIC - $ - $) -target_link_libraries(libRADOS PRIVATE - osdc ceph-common cls_lock_client fmt::fmt - ${BLKID_LIBRARIES} ${CRYPTO_LIBS} ${EXTRALIBS}) - -# if(ENABLE_SHARED) -# add_library(libRADOS ${CEPH_SHARED} -# $ -# $ -# $) -# set_target_properties(libRADOS PROPERTIES -# OUTPUT_NAME RADOS -# VERSION 0.0.1 -# SOVERSION 1 -# CXX_VISIBILITY_PRESET hidden -# VISIBILITY_INLINES_HIDDEN ON) -# if(NOT APPLE) -# set_property(TARGET libRADOS APPEND_STRING PROPERTY -# LINK_FLAGS " -Wl,--exclude-libs,ALL") -# endif() -# else(ENABLE_SHARED) -# add_library(libRADOS STATIC -# $ -# $) -# endif(ENABLE_SHARED) -# target_link_libraries(libRADOS PRIVATE -# osdc ceph-common cls_lock_client -# ${BLKID_LIBRARIES} ${CRYPTO_LIBS} ${EXTRALIBS}) -# target_link_libraries(libRADOS ${rados_libs}) -# install(TARGETS libRADOS DESTINATION ${CMAKE_INSTALL_LIBDIR}) diff --git a/src/RADOS/RADOS.cc b/src/RADOS/RADOS.cc deleted file mode 100644 index e0a900fa8e2d7..0000000000000 --- a/src/RADOS/RADOS.cc +++ /dev/null @@ -1,1475 +0,0 @@ -// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- -// vim: ts=8 sw=2 smarttab -/* - * Ceph - scalable distributed file system - * - * Copyright (C) 2018 Red Hat - * - * This is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License version 2.1, as published by the Free Software - * Foundation. See file COPYING. - * - */ - -#define BOOST_BIND_NO_PLACEHOLDERS - -#include -#include - -#include - -#include - -#include "include/ceph_fs.h" -#include "common/ceph_context.h" -#include "common/ceph_argparse.h" -#include "common/common_init.h" -#include "common/hobject.h" - -#include "global/global_init.h" - -#include "osd/osd_types.h" -#include "osdc/error_code.h" - -#include "RADOS/RADOSImpl.h" -#include "include/RADOS/RADOS.hpp" - -namespace bc = boost::container; -namespace bs = boost::system; -namespace ca = ceph::async; -namespace cb = ceph::buffer; - -namespace RADOS { -// Object - -Object::Object(std::string_view s) { - static_assert(impl_size >= sizeof(object_t)); - new (&impl) object_t(s); -} - -Object::Object(std::string&& s) { - static_assert(impl_size >= sizeof(object_t)); - new (&impl) object_t(std::move(s)); -} - -Object::Object(const std::string& s) { - static_assert(impl_size >= sizeof(object_t)); - new (&impl) object_t(s); -} - -Object::~Object() { - reinterpret_cast(&impl)->~object_t(); -} - -Object::Object(const Object& o) { - static_assert(impl_size >= sizeof(object_t)); - new (&impl) object_t(*reinterpret_cast(&o.impl)); -} -Object& Object::operator =(const Object& o) { - *reinterpret_cast(&impl) = - *reinterpret_cast(&o.impl); - return *this; -} -Object::Object(Object&& o) { - static_assert(impl_size >= sizeof(object_t)); - new (&impl) object_t(std::move(*reinterpret_cast(&o.impl))); -} -Object& Object::operator =(Object&& o) { - *reinterpret_cast(&impl) = - std::move(*reinterpret_cast(&o.impl)); - return *this; -} - -Object::operator std::string_view() const { - return std::string_view(reinterpret_cast(&impl)->name); -} - -bool operator <(const Object& lhs, const Object& rhs) { - return (*reinterpret_cast(&lhs.impl) < - *reinterpret_cast(&rhs.impl)); -} -bool operator <=(const Object& lhs, const Object& rhs) { - return (*reinterpret_cast(&lhs.impl) <= - *reinterpret_cast(&rhs.impl)); -} -bool operator >=(const Object& lhs, const Object& rhs) { - return (*reinterpret_cast(&lhs.impl) >= - *reinterpret_cast(&rhs.impl)); -} -bool operator >(const Object& lhs, const Object& rhs) { - return (*reinterpret_cast(&lhs.impl) > - *reinterpret_cast(&rhs.impl)); -} - -bool operator ==(const Object& lhs, const Object& rhs) { - return (*reinterpret_cast(&lhs.impl) == - *reinterpret_cast(&rhs.impl)); -} -bool operator !=(const Object& lhs, const Object& rhs) { - return (*reinterpret_cast(&lhs.impl) != - *reinterpret_cast(&rhs.impl)); -} - -std::ostream& operator <<(std::ostream& m, const Object& o) { - return (m << *reinterpret_cast(&o.impl)); -} - -// IOContext - -struct IOContextImpl { - object_locator_t oloc; - snapid_t snap_seq = CEPH_NOSNAP; - SnapContext snapc; -}; - -IOContext::IOContext() { - static_assert(impl_size >= sizeof(IOContextImpl)); - new (&impl) IOContextImpl(); -} - -IOContext::IOContext(std::int64_t _pool) : IOContext() { - pool(_pool); -} - -IOContext::IOContext(std::int64_t _pool, std::string_view _ns) - : IOContext() { - pool(_pool); - ns(_ns); -} - -IOContext::IOContext(std::int64_t _pool, std::string&& _ns) - : IOContext() { - pool(_pool); - ns(std::move(_ns)); -} - -IOContext::~IOContext() { - reinterpret_cast(&impl)->~IOContextImpl(); -} - -IOContext::IOContext(const IOContext& rhs) { - static_assert(impl_size >= sizeof(IOContextImpl)); - new (&impl) IOContextImpl(*reinterpret_cast(&rhs.impl)); -} - -IOContext& IOContext::operator =(const IOContext& rhs) { - *reinterpret_cast(&impl) = - *reinterpret_cast(&rhs.impl); - return *this; -} - -IOContext::IOContext(IOContext&& rhs) { - static_assert(impl_size >= sizeof(IOContextImpl)); - new (&impl) IOContextImpl( - std::move(*reinterpret_cast(&rhs.impl))); -} - -IOContext& IOContext::operator =(IOContext&& rhs) { - *reinterpret_cast(&impl) = - std::move(*reinterpret_cast(&rhs.impl)); - return *this; -} - -std::int64_t IOContext::pool() const { - return reinterpret_cast(&impl)->oloc.pool; -} - -void IOContext::pool(std::int64_t _pool) { - reinterpret_cast(&impl)->oloc.pool = _pool; -} - -std::string_view IOContext::ns() const { - return reinterpret_cast(&impl)->oloc.nspace; -} - -void IOContext::ns(std::string_view _ns) { - reinterpret_cast(&impl)->oloc.nspace = _ns; -} - -void IOContext::ns(std::string&& _ns) { - reinterpret_cast(&impl)->oloc.nspace = std::move(_ns); -} - -std::optional IOContext::key() const { - auto& oloc = reinterpret_cast(&impl)->oloc; - if (oloc.key.empty()) - return std::nullopt; - else - return std::string_view(oloc.key); -} - -void IOContext::key(std::string_view _key) { - auto& oloc = reinterpret_cast(&impl)->oloc; - if (_key.empty()) { - throw bs::system_error(EINVAL, - bs::system_category(), - "An empty key is no key at all."); - } else { - oloc.hash = -1; - oloc.key = _key; - } -} - -void IOContext::key(std::string&&_key) { - auto& oloc = reinterpret_cast(&impl)->oloc; - if (_key.empty()) { - throw bs::system_error(EINVAL, - bs::system_category(), - "An empty key is no key at all."); - } else { - oloc.hash = -1; - oloc.key = std::move(_key); - } -} - -void IOContext::clear_key() { - auto& oloc = reinterpret_cast(&impl)->oloc; - oloc.hash = -1; - oloc.key.clear(); -} - -std::optional IOContext::hash() const { - auto& oloc = reinterpret_cast(&impl)->oloc; - if (oloc.hash < 0) - return std::nullopt; - else - return oloc.hash; -} - -void IOContext::hash(std::int64_t _hash) { - auto& oloc = reinterpret_cast(&impl)->oloc; - if (_hash < 0) { - throw bs::system_error(EINVAL, - bs::system_category(), - "A negative hash is no hash at all."); - } else { - oloc.hash = _hash; - oloc.key.clear(); - } -} - -void IOContext::clear_hash() { - auto& oloc = reinterpret_cast(&impl)->oloc; - oloc.hash = -1; - oloc.key.clear(); -} - - -std::optional IOContext::read_snap() const { - auto& snap_seq = reinterpret_cast(&impl)->snap_seq; - if (snap_seq == CEPH_NOSNAP) - return std::nullopt; - else - return snap_seq; -} -void IOContext::read_snap(std::optional _snapid) { - auto& snap_seq = reinterpret_cast(&impl)->snap_seq; - snap_seq = _snapid.value_or(CEPH_NOSNAP); -} - -std::optional< - std::pair>> IOContext::write_snap_context() const { - auto& snapc = reinterpret_cast(&impl)->snapc; - if (snapc.empty()) { - return std::nullopt; - } else { - std::vector v(snapc.snaps.begin(), snapc.snaps.end()); - return std::make_optional(std::make_pair(uint64_t(snapc.seq), v)); - } -} - -void IOContext::write_snap_context( - std::optional>> _snapc) { - auto& snapc = reinterpret_cast(&impl)->snapc; - if (!_snapc) { - snapc.clear(); - } else { - SnapContext n(_snapc->first, { _snapc->second.begin(), _snapc->second.end()}); - if (!n.is_valid()) { - throw bs::system_error(EINVAL, - bs::system_category(), - "Invalid snap context."); - - } else { - snapc = n; - } - } -} - -// Op - -struct OpImpl { - ObjectOperation op; - std::optional mtime; - - OpImpl() = default; - - OpImpl(const OpImpl& rhs) = delete; - OpImpl(OpImpl&& rhs) = default; - - OpImpl& operator =(const OpImpl& rhs) = delete; - OpImpl& operator =(OpImpl&& rhs) = default; -}; - -Op::Op() { - static_assert(Op::impl_size >= sizeof(OpImpl)); - new (&impl) OpImpl; -} - -Op::Op(Op&& rhs) { - new (&impl) OpImpl(std::move(*reinterpret_cast(&rhs.impl))); -} -Op& Op::operator =(Op&& rhs) { - reinterpret_cast(&impl)->~OpImpl(); - new (&impl) OpImpl(std::move(*reinterpret_cast(&rhs.impl))); - return *this; -} -Op::~Op() { - reinterpret_cast(&impl)->~OpImpl(); -} - -void Op::set_excl() { - reinterpret_cast(&impl)->op.set_last_op_flags(CEPH_OSD_OP_FLAG_EXCL); -} -void Op::set_failok() { - reinterpret_cast(&impl)->op.set_last_op_flags( - CEPH_OSD_OP_FLAG_FAILOK); -} -void Op::set_fadvise_random() { - reinterpret_cast(&impl)->op.set_last_op_flags( - CEPH_OSD_OP_FLAG_FADVISE_RANDOM); -} -void Op::set_fadvise_sequential() { - reinterpret_cast(&impl)->op.set_last_op_flags( - CEPH_OSD_OP_FLAG_FADVISE_SEQUENTIAL); -} -void Op::set_fadvise_willneed() { - reinterpret_cast(&impl)->op.set_last_op_flags( - CEPH_OSD_OP_FLAG_FADVISE_WILLNEED); -} -void Op::set_fadvise_dontneed() { - reinterpret_cast(&impl)->op.set_last_op_flags( - CEPH_OSD_OP_FLAG_FADVISE_DONTNEED); -} -void Op::set_fadvise_nocache() { - reinterpret_cast(&impl)->op.set_last_op_flags( - CEPH_OSD_OP_FLAG_FADVISE_NOCACHE); -} - -void Op::cmpext(uint64_t off, bufferlist&& cmp_bl, std::size_t* s) { - reinterpret_cast(&impl)->op.cmpext(off, std::move(cmp_bl), nullptr, - s); -} -void Op::cmpxattr(std::string_view name, cmpxattr_op op, const bufferlist& val) { - reinterpret_cast(&impl)-> - op.cmpxattr(name, std::uint8_t(op), CEPH_OSD_CMPXATTR_MODE_STRING, val); -} -void Op::cmpxattr(std::string_view name, cmpxattr_op op, std::uint64_t val) { - bufferlist bl; - encode(val, bl); - reinterpret_cast(&impl)-> - op.cmpxattr(name, std::uint8_t(op), CEPH_OSD_CMPXATTR_MODE_U64, bl); -} - -void Op::assert_version(uint64_t ver) { - reinterpret_cast(&impl)->op.assert_version(ver); -} -void Op::assert_exists() { - reinterpret_cast(&impl)->op.stat( - nullptr, - static_cast(nullptr), - static_cast(nullptr)); -} -void Op::cmp_omap(const bc::flat_map< - std::string, std::pair>& assertions) { - reinterpret_cast(&impl)->op.omap_cmp(assertions, nullptr); -} - -std::size_t Op::size() const { - return reinterpret_cast(&impl)->op.size(); -} - -std::ostream& operator <<(std::ostream& m, const Op& o) { - return m << reinterpret_cast(&o.impl)->op; -} - - -// --- - -// ReadOp / WriteOp - -void ReadOp::read(size_t off, uint64_t len, cb::list* out, - bs::error_code* ec) { - reinterpret_cast(&impl)->op.read(off, len, ec, out); -} - -void ReadOp::get_xattr(std::string_view name, cb::list* out, - bs::error_code* ec) { - reinterpret_cast(&impl)->op.getxattr(name, ec, out); -} - -void ReadOp::get_omap_header(cb::list* out, - bs::error_code* ec) { - reinterpret_cast(&impl)->op.omap_get_header(ec, out); -} - -void ReadOp::sparse_read(uint64_t off, uint64_t len, cb::list* out, - std::vector>* extents, - bs::error_code* ec) { - reinterpret_cast(&impl)->op.sparse_read(off, len, ec, extents, out); -} - -void ReadOp::stat(std::uint64_t* size, ceph::real_time* mtime, - bs::error_code* ec) { - reinterpret_cast(&impl)->op.stat(size, mtime, ec); -} - -void ReadOp::get_omap_keys(std::optional start_after, - std::uint64_t max_return, - bc::flat_set* keys, - bool* done, - bs::error_code* ec) { - reinterpret_cast(&impl)->op.omap_get_keys(start_after, max_return, - ec, keys, done); -} - -void ReadOp::get_xattrs(bc::flat_map* kv, - bs::error_code* ec) { - reinterpret_cast(&impl)->op.getxattrs(ec, kv); -} - -void ReadOp::get_omap_vals(std::optional start_after, - std::optional filter_prefix, - uint64_t max_return, - bc::flat_map* kv, - bool* done, - bs::error_code* ec) { - reinterpret_cast(&impl)->op.omap_get_vals(start_after, filter_prefix, - max_return, ec, kv, done); -} - -void ReadOp::get_omap_vals_by_keys( - const bc::flat_set& keys, - bc::flat_map* kv, - bs::error_code* ec) { - reinterpret_cast(&impl)->op.omap_get_vals_by_keys(keys, ec, kv); -} - -void ReadOp::list_watchers(std::vector* watchers, - bs::error_code* ec) { - reinterpret_cast(&impl)-> op.list_watchers(watchers, ec); -} - -void ReadOp::list_snaps(librados::snap_set_t* snaps, - bs::error_code* ec) { - reinterpret_cast(&impl)->op.list_snaps(snaps, nullptr, ec); -} - -void ReadOp::exec(std::string_view cls, std::string_view method, - const bufferlist& inbl, - cb::list* out, - bs::error_code* ec) { - reinterpret_cast(&impl)->op.call(cls, method, inbl, ec, out); -} - -void ReadOp::exec(std::string_view cls, std::string_view method, - const bufferlist& inbl, - fu2::unique_function f) { - reinterpret_cast(&impl)->op.call(cls, method, inbl, std::move(f)); -} - -// WriteOp - -void WriteOp::set_mtime(ceph::real_time t) { - auto o = reinterpret_cast(&impl); - o->mtime = t; -} - -void WriteOp::create(bool exclusive) { - reinterpret_cast(&impl)->op.create(exclusive); -} - -void WriteOp::write(uint64_t off, bufferlist&& bl) { - reinterpret_cast(&impl)->op.write(off, bl); -} - -void WriteOp::write_full(bufferlist&& bl) { - reinterpret_cast(&impl)->op.write_full(bl); -} - -void WriteOp::writesame(uint64_t off, uint64_t write_len, bufferlist&& bl) { - reinterpret_cast(&impl)->op.writesame(off, write_len, bl); -} - -void WriteOp::append(bufferlist&& bl) { - reinterpret_cast(&impl)->op.append(bl); -} - -void WriteOp::remove() { - reinterpret_cast(&impl)->op.remove(); -} - -void WriteOp::truncate(uint64_t off) { - reinterpret_cast(&impl)->op.truncate(off); -} - -void WriteOp::zero(uint64_t off, uint64_t len) { - reinterpret_cast(&impl)->op.zero(off, len); -} - -void WriteOp::rmxattr(std::string_view name) { - reinterpret_cast(&impl)->op.rmxattr(name); -} - -void WriteOp::setxattr(std::string_view name, - bufferlist&& bl) { - reinterpret_cast(&impl)->op.setxattr(name, bl); -} - -void WriteOp::rollback(uint64_t snapid) { - reinterpret_cast(&impl)->op.rollback(snapid); -} - -void WriteOp::set_omap( - const bc::flat_map& map) { - reinterpret_cast(&impl)->op.omap_set(map); -} - -void WriteOp::set_omap_header(bufferlist&& bl) { - reinterpret_cast(&impl)->op.omap_set_header(bl); -} - -void WriteOp::clear_omap() { - reinterpret_cast(&impl)->op.omap_clear(); -} - -void WriteOp::rm_omap_keys( - const bc::flat_set& to_rm) { - reinterpret_cast(&impl)->op.omap_rm_keys(to_rm); -} - -void WriteOp::set_alloc_hint(uint64_t expected_object_size, - uint64_t expected_write_size, - alloc_hint::alloc_hint_t flags) { - reinterpret_cast(&impl)->op.set_alloc_hint(expected_object_size, - expected_write_size, - flags); -} - -void WriteOp::exec(std::string_view cls, std::string_view method, - const bufferlist& inbl, bs::error_code* ec) { - reinterpret_cast(&impl)->op.call(cls, method, inbl, ec); -} - -// RADOS - -RADOS::Builder& RADOS::Builder::add_conf_file(std::string_view f) { - if (conf_files) - *conf_files += (", " + std::string(f)); - else - conf_files = std::string(f); - return *this; -} - -void RADOS::Builder::build(boost::asio::io_context& ioctx, - std::unique_ptr c) { - constexpr auto env = CODE_ENVIRONMENT_LIBRARY; - CephInitParameters ci(env); - if (name) - ci.name.set(CEPH_ENTITY_TYPE_CLIENT, *name); - else - ci.name.set(CEPH_ENTITY_TYPE_CLIENT, "admin"); - uint32_t flags = 0; - if (no_default_conf) - flags |= CINIT_FLAG_NO_DEFAULT_CONFIG_FILE; - if (no_mon_conf) - flags |= CINIT_FLAG_NO_MON_CONFIG; - - CephContext *cct = common_preinit(ci, env, flags); - if (cluster) - cct->_conf->cluster = *cluster; - - if (no_mon_conf) - cct->_conf->no_mon_config = true; - - // TODO: Come up with proper error codes here. Maybe augment the - // functions with a default bs::error_code* parameter to - // pass back. - { - std::ostringstream ss; - auto r = cct->_conf.parse_config_files(conf_files ? conf_files->data() : nullptr, - &ss, flags); - if (r < 0) - c->dispatch(std::move(c), ceph::to_error_code(r), RADOS{nullptr}); - } - - cct->_conf.parse_env(cct->get_module_type()); - - for (const auto& [n, v] : configs) { - std::stringstream ss; - auto r = cct->_conf.set_val(n, v, &ss); - if (r < 0) - c->dispatch(std::move(c), ceph::to_error_code(-EINVAL), RADOS{nullptr}); - } - - if (!no_mon_conf) { - MonClient mc_bootstrap(cct, ioctx); - // TODO This function should return an error code. - auto err = mc_bootstrap.get_monmap_and_config(); - if (err < 0) - c->dispatch(std::move(c), ceph::to_error_code(err), RADOS{nullptr}); - } - if (!cct->_log->is_started()) { - cct->_log->start(); - } - common_init_finish(cct); - - RADOS::make_with_cct(cct, ioctx, std::move(c)); -} - -void RADOS::make_with_cct(CephContext* cct, - boost::asio::io_context& ioctx, - std::unique_ptr c) { - try { - auto r = new detail::RADOS(ioctx, cct); - r->objecter->wait_for_osd_map( - [c = std::move(c), r = std::unique_ptr(r)]() mutable { - c->dispatch(std::move(c), bs::error_code{}, - RADOS{std::move(r)}); - }); - } catch (const bs::system_error& err) { - c->dispatch(std::move(c), err.code(), RADOS{nullptr}); - } -} - - -RADOS::RADOS() = default; - -RADOS::RADOS(std::unique_ptr impl) - : impl(std::move(impl)) {} - -RADOS::RADOS(RADOS&&) = default; -RADOS& RADOS::operator =(RADOS&&) = default; - -RADOS::~RADOS() = default; - -RADOS::executor_type RADOS::get_executor() { - return impl->ioctx.get_executor(); -} - -void RADOS::execute(const Object& o, const IOContext& _ioc, ReadOp&& _op, - cb::list* bl, - std::unique_ptr c, version_t* objver) { - auto oid = reinterpret_cast(&o.impl); - auto ioc = reinterpret_cast(&_ioc.impl); - auto op = reinterpret_cast(&_op.impl); - auto flags = 0; // Should be in Op. - - impl->objecter->read( - *oid, ioc->oloc, std::move(op->op), ioc->snap_seq, bl, flags, - std::move(c), objver); -} - -void RADOS::execute(const Object& o, const IOContext& _ioc, WriteOp&& _op, - std::unique_ptr c, version_t* objver) { - auto oid = reinterpret_cast(&o.impl); - auto ioc = reinterpret_cast(&_ioc.impl); - auto op = reinterpret_cast(&_op.impl); - auto flags = 0; // Should be in Op. - ceph::real_time mtime; - if (op->mtime) - mtime = *op->mtime; - else - mtime = ceph::real_clock::now(); - - impl->objecter->mutate( - *oid, ioc->oloc, std::move(op->op), ioc->snapc, - mtime, flags, - std::move(c), objver); -} - -void RADOS::execute(const Object& o, std::int64_t pool, ReadOp&& _op, - cb::list* bl, - std::unique_ptr c, - std::optional ns, - std::optional key, - version_t* objver) { - auto oid = reinterpret_cast(&o.impl); - auto op = reinterpret_cast(&_op.impl); - auto flags = 0; // Should be in Op. - object_locator_t oloc; - oloc.pool = pool; - if (ns) - oloc.nspace = *ns; - if (key) - oloc.key = *key; - - impl->objecter->read( - *oid, oloc, std::move(op->op), CEPH_NOSNAP, bl, flags, - std::move(c), objver); -} - -void RADOS::execute(const Object& o, std::int64_t pool, WriteOp&& _op, - std::unique_ptr c, - std::optional ns, - std::optional key, - version_t* objver) { - auto oid = reinterpret_cast(&o.impl); - auto op = reinterpret_cast(&_op.impl); - auto flags = 0; // Should be in Op. - object_locator_t oloc; - oloc.pool = pool; - if (ns) - oloc.nspace = *ns; - if (key) - oloc.key = *key; - - ceph::real_time mtime; - if (op->mtime) - mtime = *op->mtime; - else - mtime = ceph::real_clock::now(); - - impl->objecter->mutate( - *oid, oloc, std::move(op->op), {}, - mtime, flags, - std::move(c), objver); -} - -boost::uuids::uuid RADOS::get_fsid() const noexcept { - return impl->monclient.get_fsid().uuid; -} - - -void RADOS::lookup_pool(std::string_view name, - std::unique_ptr c) -{ - // I kind of want to make lookup_pg_pool return - // std::optional since it can only return one error code. - int64_t ret = impl->objecter->with_osdmap( - std::mem_fn(&OSDMap::lookup_pg_pool_name), - name); - if (ret < 0) { - impl->objecter->wait_for_latest_osdmap( - [name = std::string(name), c = std::move(c), - objecter = impl->objecter.get()] - (bs::error_code ec) mutable { - int64_t ret = - objecter->with_osdmap(std::mem_fn(&OSDMap::lookup_pg_pool_name), - name); - if (ret < 0) - ca::dispatch(std::move(c), osdc_errc::pool_dne, - std::int64_t(0)); - else - ca::dispatch(std::move(c), bs::error_code{}, ret); - }); - } else if (ret < 0) { - ca::dispatch(std::move(c), osdc_errc::pool_dne, - std::int64_t(0)); - } else { - ca::dispatch(std::move(c), bs::error_code{}, ret); - } -} - - -std::optional RADOS::get_pool_alignment(int64_t pool_id) -{ - return impl->objecter->with_osdmap( - [pool_id](const OSDMap &o) -> std::optional { - if (!o.have_pg_pool(pool_id)) { - throw bs::system_error( - ENOENT, bs::system_category(), - "Cannot find pool in OSDMap."); - } else if (o.get_pg_pool(pool_id)->requires_aligned_append()) { - return o.get_pg_pool(pool_id)->required_alignment(); - } else { - return std::nullopt; - } - }); -} - -void RADOS::list_pools(std::unique_ptr c) { - impl->objecter->with_osdmap( - [&](OSDMap& o) { - std::vector> v; - for (auto p : o.get_pools()) - v.push_back(std::make_pair(p.first, o.get_pool_name(p.first))); - ca::dispatch(std::move(c), std::move(v)); - }); -} - -void RADOS::create_pool_snap(std::int64_t pool, - std::string_view snapName, - std::unique_ptr c) -{ - impl->objecter->create_pool_snap( - pool, snapName, - Objecter::PoolOp::OpComp::create( - get_executor(), - [c = std::move(c)](bs::error_code e, const bufferlist&) mutable { - ca::dispatch(std::move(c), e); - })); -} - -void RADOS::allocate_selfmanaged_snap(int64_t pool, - std::unique_ptr c) { - impl->objecter->allocate_selfmanaged_snap( - pool, - ca::Completion::create( - get_executor(), - [c = std::move(c)](bs::error_code e, snapid_t snap) mutable { - ca::dispatch(std::move(c), e, snap); - })); -} - -void RADOS::delete_pool_snap(std::int64_t pool, - std::string_view snapName, - std::unique_ptr c) -{ - impl->objecter->delete_pool_snap( - pool, snapName, - Objecter::PoolOp::OpComp::create( - get_executor(), - [c = std::move(c)](bs::error_code e, const bufferlist&) mutable { - ca::dispatch(std::move(c), e); - })); -} - -void RADOS::delete_selfmanaged_snap(std::int64_t pool, - snapid_t snap, - std::unique_ptr c) -{ - impl->objecter->delete_selfmanaged_snap( - pool, snap, - Objecter::PoolOp::OpComp::create( - get_executor(), - [c = std::move(c)](bs::error_code e, const bufferlist&) mutable { - ca::dispatch(std::move(c), e); - })); -} - -void RADOS::create_pool(std::string_view name, - std::optional crush_rule, - std::unique_ptr c) -{ - impl->objecter->create_pool( - name, - Objecter::PoolOp::OpComp::create( - get_executor(), - [c = std::move(c)](bs::error_code e, const bufferlist&) mutable { - ca::dispatch(std::move(c), e); - }), - crush_rule.value_or(-1)); -} - -void RADOS::delete_pool(std::string_view name, - std::unique_ptr c) -{ - impl->objecter->delete_pool( - name, - Objecter::PoolOp::OpComp::create( - get_executor(), - [c = std::move(c)](bs::error_code e, const bufferlist&) mutable { - ca::dispatch(std::move(c), e); - })); -} - -void RADOS::delete_pool(std::int64_t pool, - std::unique_ptr c) -{ - impl->objecter->delete_pool( - pool, - Objecter::PoolOp::OpComp::create( - get_executor(), - [c = std::move(c)](bs::error_code e, const bufferlist&) mutable { - ca::dispatch(std::move(c), e); - })); -} - -void RADOS::stat_pools(const std::vector& pools, - std::unique_ptr c) { - impl->objecter->get_pool_stats( - pools, - [c = std::move(c)] - (bs::error_code ec, - bc::flat_map s, - bool p) mutable { - ca::dispatch(std::move(c), ec, std::move(s), p); - }); -} - -void RADOS::stat_fs(std::optional _pool, - std::unique_ptr c) { - boost::optional pool; - if (_pool) - pool = *pool; - impl->objecter->get_fs_stats(pool, std::move(c)); -} - -// --- Watch/Notify - -void RADOS::watch(const Object& o, const IOContext& _ioc, - std::optional timeout, WatchCB&& cb, - std::unique_ptr c) { - auto oid = reinterpret_cast(&o.impl); - auto ioc = reinterpret_cast(&_ioc.impl); - - ObjectOperation op; - - auto linger_op = impl->objecter->linger_register(*oid, ioc->oloc, 0); - uint64_t cookie = linger_op->get_cookie(); - linger_op->handle = std::move(cb); - op.watch(cookie, CEPH_OSD_WATCH_OP_WATCH, timeout.value_or(0s).count()); - bufferlist bl; - impl->objecter->linger_watch( - linger_op, op, ioc->snapc, ceph::real_clock::now(), bl, - Objecter::LingerOp::OpComp::create( - get_executor(), - [c = std::move(c), cookie](bs::error_code e, cb::list) mutable { - ca::dispatch(std::move(c), e, cookie); - }), nullptr); -} - -void RADOS::watch(const Object& o, std::int64_t pool, - std::optional timeout, WatchCB&& cb, - std::unique_ptr c, - std::optional ns, - std::optional key) { - auto oid = reinterpret_cast(&o.impl); - object_locator_t oloc; - oloc.pool = pool; - if (ns) - oloc.nspace = *ns; - if (key) - oloc.key = *key; - - ObjectOperation op; - - Objecter::LingerOp *linger_op = impl->objecter->linger_register(*oid, oloc, 0); - uint64_t cookie = linger_op->get_cookie(); - linger_op->handle = std::move(cb); - op.watch(cookie, CEPH_OSD_WATCH_OP_WATCH, timeout.value_or(0s).count()); - bufferlist bl; - impl->objecter->linger_watch( - linger_op, op, {}, ceph::real_clock::now(), bl, - Objecter::LingerOp::OpComp::create( - get_executor(), - [c = std::move(c), cookie](bs::error_code e, bufferlist) mutable { - ca::dispatch(std::move(c), e, cookie); - }), nullptr); -} - -void RADOS::notify_ack(const Object& o, - const IOContext& _ioc, - uint64_t notify_id, - uint64_t cookie, - bufferlist&& bl, - std::unique_ptr c) -{ - auto oid = reinterpret_cast(&o.impl); - auto ioc = reinterpret_cast(&_ioc.impl); - - ObjectOperation op; - op.notify_ack(notify_id, cookie, bl); - - impl->objecter->read(*oid, ioc->oloc, std::move(op), ioc->snap_seq, - nullptr, 0, std::move(c)); -} - -void RADOS::notify_ack(const Object& o, - std::int64_t pool, - uint64_t notify_id, - uint64_t cookie, - bufferlist&& bl, - std::unique_ptr c, - std::optional ns, - std::optional key) { - auto oid = reinterpret_cast(&o.impl); - object_locator_t oloc; - oloc.pool = pool; - if (ns) - oloc.nspace = *ns; - if (key) - oloc.key = *key; - - ObjectOperation op; - op.notify_ack(notify_id, cookie, bl); - impl->objecter->read(*oid, oloc, std::move(op), CEPH_NOSNAP, nullptr, 0, - std::move(c)); -} - -tl::expected RADOS::watch_check(uint64_t cookie) -{ - Objecter::LingerOp *linger_op = reinterpret_cast(cookie); - return impl->objecter->linger_check(linger_op); -} - -void RADOS::unwatch(uint64_t cookie, const IOContext& _ioc, - std::unique_ptr c) -{ - auto ioc = reinterpret_cast(&_ioc.impl); - - Objecter::LingerOp *linger_op = reinterpret_cast(cookie); - - ObjectOperation op; - op.watch(cookie, CEPH_OSD_WATCH_OP_UNWATCH); - impl->objecter->mutate(linger_op->target.base_oid, ioc->oloc, std::move(op), - ioc->snapc, ceph::real_clock::now(), 0, - Objecter::Op::OpComp::create( - get_executor(), - [objecter = impl->objecter.get(), - linger_op, c = std::move(c)] - (bs::error_code ec) mutable { - objecter->linger_cancel(linger_op); - ca::dispatch(std::move(c), ec); - })); -} - -void RADOS::unwatch(uint64_t cookie, std::int64_t pool, - std::unique_ptr c, - std::optional ns, - std::optional key) -{ - object_locator_t oloc; - oloc.pool = pool; - if (ns) - oloc.nspace = *ns; - if (key) - oloc.key = *key; - - Objecter::LingerOp *linger_op = reinterpret_cast(cookie); - - ObjectOperation op; - op.watch(cookie, CEPH_OSD_WATCH_OP_UNWATCH); - impl->objecter->mutate(linger_op->target.base_oid, oloc, std::move(op), - {}, ceph::real_clock::now(), 0, - Objecter::Op::OpComp::create( - get_executor(), - [objecter = impl->objecter.get(), - linger_op, c = std::move(c)] - (bs::error_code ec) mutable { - objecter->linger_cancel(linger_op); - ca::dispatch(std::move(c), ec); - })); -} - -void RADOS::flush_watch(std::unique_ptr c) -{ - impl->objecter->linger_callback_flush([c = std::move(c)]() mutable { - ca::post(std::move(c)); - }); -} - -struct NotifyHandler : std::enable_shared_from_this { - boost::asio::io_context& ioc; - boost::asio::io_context::strand strand; - Objecter* objecter; - Objecter::LingerOp* op; - std::unique_ptr c; - - bool acked = false; - bool finished = false; - bs::error_code res; - bufferlist rbl; - - NotifyHandler(boost::asio::io_context& ioc, - Objecter* objecter, - Objecter::LingerOp* op, - std::unique_ptr c) - : ioc(ioc), strand(ioc), objecter(objecter), op(op), c(std::move(c)) {} - - // Use bind or a lambda to pass this in. - void handle_ack(bs::error_code ec, - bufferlist&&) { - boost::asio::post( - strand, - [this, ec, p = shared_from_this()]() mutable { - acked = true; - maybe_cleanup(ec); - }); - } - - // Notify finish callback. It can actually own the object's storage. - - void operator()(bs::error_code ec, - bufferlist&& bl) { - boost::asio::post( - strand, - [this, ec, p = shared_from_this()]() mutable { - finished = true; - maybe_cleanup(ec); - }); - } - - // Should be called from strand. - void maybe_cleanup(bs::error_code ec) { - if (!res && ec) - res = ec; - if ((acked && finished) || res) { - objecter->linger_cancel(op); - ceph_assert(c); - ca::dispatch(std::move(c), res, std::move(rbl)); - } - } -}; - -void RADOS::notify(const Object& o, const IOContext& _ioc, bufferlist&& bl, - std::optional timeout, - std::unique_ptr c) -{ - auto oid = reinterpret_cast(&o.impl); - auto ioc = reinterpret_cast(&_ioc.impl); - auto linger_op = impl->objecter->linger_register(*oid, ioc->oloc, 0); - - auto cb = std::make_shared(impl->ioctx, impl->objecter.get(), - linger_op, std::move(c)); - linger_op->on_notify_finish = - Objecter::LingerOp::OpComp::create( - get_executor(), - [cb](bs::error_code ec, ceph::bufferlist bl) mutable { - (*cb)(ec, std::move(bl)); - }); - ObjectOperation rd; - bufferlist inbl; - rd.notify( - linger_op->get_cookie(), 1, - timeout ? timeout->count() : impl->cct->_conf->client_notify_timeout, - bl, &inbl); - - impl->objecter->linger_notify( - linger_op, rd, ioc->snap_seq, inbl, - Objecter::LingerOp::OpComp::create( - get_executor(), - [cb](bs::error_code ec, ceph::bufferlist bl) mutable { - cb->handle_ack(ec, std::move(bl)); - }), nullptr); -} - -void RADOS::notify(const Object& o, std::int64_t pool, bufferlist&& bl, - std::optional timeout, - std::unique_ptr c, - std::optional ns, - std::optional key) -{ - auto oid = reinterpret_cast(&o.impl); - object_locator_t oloc; - oloc.pool = pool; - if (ns) - oloc.nspace = *ns; - if (key) - oloc.key = *key; - auto linger_op = impl->objecter->linger_register(*oid, oloc, 0); - - auto cb = std::make_shared(impl->ioctx, impl->objecter.get(), - linger_op, std::move(c)); - linger_op->on_notify_finish = - Objecter::LingerOp::OpComp::create( - get_executor(), - [cb](bs::error_code ec, ceph::bufferlist&& bl) mutable { - (*cb)(ec, std::move(bl)); - }); - ObjectOperation rd; - bufferlist inbl; - rd.notify( - linger_op->get_cookie(), 1, - timeout ? timeout->count() : impl->cct->_conf->client_notify_timeout, - bl, &inbl); - - impl->objecter->linger_notify( - linger_op, rd, CEPH_NOSNAP, inbl, - Objecter::LingerOp::OpComp::create( - get_executor(), - [cb](bs::error_code ec, bufferlist&& bl) mutable { - cb->handle_ack(ec, std::move(bl)); - }), nullptr); -} - -// Enumeration - -Cursor::Cursor() { - static_assert(impl_size >= sizeof(hobject_t)); - new (&impl) hobject_t(); -}; - -Cursor::Cursor(end_magic_t) { - static_assert(impl_size >= sizeof(hobject_t)); - new (&impl) hobject_t(hobject_t::get_max()); -} - -Cursor::Cursor(void* p) { - static_assert(impl_size >= sizeof(hobject_t)); - new (&impl) hobject_t(std::move(*reinterpret_cast(p))); -} - -Cursor Cursor::begin() { - Cursor e; - return e; -} - -Cursor Cursor::end() { - Cursor e(end_magic_t{}); - return e; -} - -Cursor::Cursor(const Cursor& rhs) { - static_assert(impl_size >= sizeof(hobject_t)); - new (&impl) hobject_t(*reinterpret_cast(&rhs.impl)); -} - -Cursor& Cursor::operator =(const Cursor& rhs) { - static_assert(impl_size >= sizeof(hobject_t)); - reinterpret_cast(&impl)->~hobject_t(); - new (&impl) hobject_t(*reinterpret_cast(&rhs.impl)); - return *this; -} - -Cursor::Cursor(Cursor&& rhs) { - static_assert(impl_size >= sizeof(hobject_t)); - new (&impl) hobject_t(std::move(*reinterpret_cast(&rhs.impl))); -} - -Cursor& Cursor::operator =(Cursor&& rhs) { - static_assert(impl_size >= sizeof(hobject_t)); - reinterpret_cast(&impl)->~hobject_t(); - new (&impl) hobject_t(std::move(*reinterpret_cast(&rhs.impl))); - return *this; -} -Cursor::~Cursor() { - reinterpret_cast(&impl)->~hobject_t(); -} - -bool operator ==(const Cursor& lhs, const Cursor& rhs) { - return (*reinterpret_cast(&lhs.impl) == - *reinterpret_cast(&rhs.impl)); -} - -bool operator !=(const Cursor& lhs, const Cursor& rhs) { - return (*reinterpret_cast(&lhs.impl) != - *reinterpret_cast(&rhs.impl)); -} - -bool operator <(const Cursor& lhs, const Cursor& rhs) { - return (*reinterpret_cast(&lhs.impl) < - *reinterpret_cast(&rhs.impl)); -} - -bool operator <=(const Cursor& lhs, const Cursor& rhs) { - return (*reinterpret_cast(&lhs.impl) <= - *reinterpret_cast(&rhs.impl)); -} - -bool operator >=(const Cursor& lhs, const Cursor& rhs) { - return (*reinterpret_cast(&lhs.impl) >= - *reinterpret_cast(&rhs.impl)); -} - -bool operator >(const Cursor& lhs, const Cursor& rhs) { - return (*reinterpret_cast(&lhs.impl) > - *reinterpret_cast(&rhs.impl)); -} - -std::string Cursor::to_str() const { - using namespace std::literals; - auto& h = *reinterpret_cast(&impl); - - return h.is_max() ? "MAX"s : h.to_str(); -} - -std::optional -Cursor::from_str(const std::string& s) { - Cursor e; - auto& h = *reinterpret_cast(&e.impl); - if (!h.parse(s)) - return std::nullopt; - - return e; -} - -void RADOS::enumerate_objects(const IOContext& _ioc, - const Cursor& begin, - const Cursor& end, - const std::uint32_t max, - const bufferlist& filter, - std::vector* ls, - Cursor* cursor, - std::unique_ptr c) { - auto ioc = reinterpret_cast(&_ioc.impl); - - impl->objecter->enumerate_objects( - ioc->oloc.pool, - ioc->oloc.nspace, - *reinterpret_cast(&begin.impl), - *reinterpret_cast(&end.impl), - max, - filter, - [c = std::move(c), ls, cursor] - (bs::error_code ec, std::vector&& v, - hobject_t&& n) mutable { - if (ls) - *ls = std::move(v); - if (cursor) { - Cursor next(static_cast(&n)); - *cursor = std::move(next); - } - ca::dispatch(std::move(c), ec); - }); -} - -void RADOS::enumerate_objects(std::int64_t pool, - const Cursor& begin, - const Cursor& end, - const std::uint32_t max, - const bufferlist& filter, - std::vector* ls, - Cursor* cursor, - std::unique_ptr c, - std::optional ns, - std::optional key) { - impl->objecter->enumerate_objects( - pool, - ns ? *ns : std::string_view{}, - *reinterpret_cast(&begin.impl), - *reinterpret_cast(&end.impl), - max, - filter, - [c = std::move(c), ls, cursor] - (bs::error_code ec, std::vector&& v, - hobject_t&& n) mutable { - if (ls) - *ls = std::move(v); - if (cursor) { - Cursor next(static_cast(&n)); - *cursor = std::move(next); - } - ca::dispatch(std::move(c), ec); - }); -} - -void RADOS::enumerate_objects(const IOContext& _ioc, - const Cursor& begin, - const Cursor& end, - const std::uint32_t max, - const bufferlist& filter, - std::unique_ptr c) { - auto ioc = reinterpret_cast(&_ioc.impl); - - impl->objecter->enumerate_objects( - ioc->oloc.pool, - ioc->oloc.nspace, - *reinterpret_cast(&begin.impl), - *reinterpret_cast(&end.impl), - max, - filter, - [c = std::move(c)] - (bs::error_code ec, std::vector&& v, - hobject_t&& n) mutable { - ca::dispatch(std::move(c), ec, std::move(v), - Cursor(static_cast(&n))); - }); -} - -void RADOS::enumerate_objects(std::int64_t pool, - const Cursor& begin, - const Cursor& end, - const std::uint32_t max, - const bufferlist& filter, - std::unique_ptr c, - std::optional ns, - std::optional key) { - impl->objecter->enumerate_objects( - pool, - ns ? *ns : std::string_view{}, - *reinterpret_cast(&begin.impl), - *reinterpret_cast(&end.impl), - max, - filter, - [c = std::move(c)] - (bs::error_code ec, std::vector&& v, - hobject_t&& n) mutable { - ca::dispatch(std::move(c), ec, std::move(v), - Cursor(static_cast(&n))); - }); -} - - -void RADOS::osd_command(int osd, std::vector&& cmd, - ceph::bufferlist&& in, std::unique_ptr c) { - impl->objecter->osd_command(osd, std::move(cmd), std::move(in), nullptr, - [c = std::move(c)] - (bs::error_code ec, - std::string&& s, - ceph::bufferlist&& b) mutable { - ca::dispatch(std::move(c), ec, - std::move(s), - std::move(b)); - }); -} -void RADOS::pg_command(pg_t pg, std::vector&& cmd, - ceph::bufferlist&& in, std::unique_ptr c) { - impl->objecter->pg_command(pg, std::move(cmd), std::move(in), nullptr, - [c = std::move(c)] - (bs::error_code ec, - std::string&& s, - ceph::bufferlist&& b) mutable { - ca::dispatch(std::move(c), ec, - std::move(s), - std::move(b)); - }); -} - -void RADOS::enable_application(std::string_view pool, std::string_view app_name, - bool force, std::unique_ptr c) { - // pre-Luminous clusters will return -EINVAL and application won't be - // preserved until Luminous is configured as minimum version. - if (!impl->get_required_monitor_features().contains_all( - ceph::features::mon::FEATURE_LUMINOUS)) { - ca::dispatch(std::move(c), ceph::to_error_code(-EOPNOTSUPP)); - } else { - impl->monclient.start_mon_command( - { fmt::format("{{ \"prefix\": \"osd pool application enable\"," - "\"pool\": \"{}\", \"app\": \"{}\"{}}}", - pool, app_name, - force ? " ,\"yes_i_really_mean_it\": true" : "")}, - {}, [c = std::move(c)](bs::error_code e, - std::string, cb::list) mutable { - ca::post(std::move(c), e); - }); - } -} - -void RADOS::mon_command(std::vector command, - const cb::list& bl, - std::string* outs, cb::list* outbl, - std::unique_ptr c) { - - impl->monclient.start_mon_command( - command, bl, - [c = std::move(c), outs, outbl](bs::error_code e, - std::string s, cb::list bl) mutable { - if (outs) - *outs = std::move(s); - if (outbl) - *outbl = std::move(bl); - ca::post(std::move(c), e); - }); -} - -uint64_t RADOS::instance_id() const { - return impl->get_instance_id(); -} -} - -namespace std { -size_t hash::operator ()( - const RADOS::Object& r) const { - static constexpr const hash H; - return H(*reinterpret_cast(&r.impl)); -} -} diff --git a/src/RADOS/RADOSImpl.cc b/src/RADOS/RADOSImpl.cc deleted file mode 100644 index 4dd816da5190d..0000000000000 --- a/src/RADOS/RADOSImpl.cc +++ /dev/null @@ -1,112 +0,0 @@ -// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- -// vim: ts=8 sw=2 smarttab -/* - * Ceph - scalable distributed file system - * - * Copyright (C) 2004-2012 Sage Weil - * - * This is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License version 2.1, as published by the Free Software - * Foundation. See file COPYING. - * - */ - - -#include - -#include "common/common_init.h" - -#include "global/global_init.h" - -#include "RADOSImpl.h" - -namespace RADOS { -namespace detail { - -RADOS::RADOS(boost::asio::io_context& ioctx, - boost::intrusive_ptr _cct) - : Dispatcher(_cct.detach()), - ioctx(ioctx), - monclient(cct, ioctx), - moncsd(monclient), - mgrclient(cct, nullptr, &monclient.monmap), - mgrcsd(mgrclient) { - auto err = monclient.build_initial_monmap(); - if (err < 0) - throw std::system_error(ceph::to_error_code(err)); - - messenger.reset(Messenger::create_client_messenger(cct, "radosclient")); - if (!messenger) - throw std::bad_alloc(); - - // require OSDREPLYMUX feature. this means we will fail to talk to - // old servers. this is necessary because otherwise we won't know - // how to decompose the reply data into its constituent pieces. - messenger->set_default_policy( - Messenger::Policy::lossy_client(CEPH_FEATURE_OSDREPLYMUX)); - - objecter.reset(new Objecter(cct, messenger.get(), &monclient, - ioctx, - cct->_conf->rados_mon_op_timeout, - cct->_conf->rados_osd_op_timeout)); - - objecter->set_balanced_budget(); - monclient.set_messenger(messenger.get()); - mgrclient.set_messenger(messenger.get()); - objecter->init(); - messenger->add_dispatcher_head(&mgrclient); - messenger->add_dispatcher_tail(objecter.get()); - messenger->start(); - monclient.set_want_keys(CEPH_ENTITY_TYPE_MON | CEPH_ENTITY_TYPE_OSD | CEPH_ENTITY_TYPE_MGR); - err = monclient.init(); - if (err) { - throw boost::system::system_error(ceph::to_error_code(err)); - } - err = monclient.authenticate(cct->_conf->client_mount_timeout); - if (err) { - throw boost::system::system_error(ceph::to_error_code(err)); - } - messenger->set_myname(entity_name_t::CLIENT(monclient.get_global_id())); - // Detect older cluster, put mgrclient into compatible mode - mgrclient.set_mgr_optional( - !get_required_monitor_features().contains_all( - ceph::features::mon::FEATURE_LUMINOUS)); - - // MgrClient needs this (it doesn't have MonClient reference itself) - monclient.sub_want("mgrmap", 0, 0); - monclient.renew_subs(); - - mgrclient.init(); - objecter->set_client_incarnation(0); - objecter->start(); - - messenger->add_dispatcher_tail(this); - - std::unique_lock l(lock); - instance_id = monclient.get_global_id(); -} - -bool RADOS::ms_dispatch(Message *m) -{ - switch (m->get_type()) { - // OSD - case CEPH_MSG_OSD_MAP: - m->put(); - return true; - } - return false; -} - -void RADOS::ms_handle_connect(Connection *con) {} -bool RADOS::ms_handle_reset(Connection *con) { - return false; -} -void RADOS::ms_handle_remote_reset(Connection *con) {} -bool RADOS::ms_handle_refused(Connection *con) { - return false; -} - -RADOS::~RADOS() = default; -} -} diff --git a/src/RADOS/RADOSImpl.h b/src/RADOS/RADOSImpl.h deleted file mode 100644 index c7ce18a9e7dd9..0000000000000 --- a/src/RADOS/RADOSImpl.h +++ /dev/null @@ -1,105 +0,0 @@ -// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- -// vim: ts=8 sw=2 smarttab -/* - * Ceph - scalable distributed file system - * - * Copyright (C) 2004-2012 Sage Weil - * - * This is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License version 2.1, as published by the Free Software - * Foundation. See file COPYING. - * - */ -#ifndef CEPH_LIBRADOS_RADOSCLIENT_H -#define CEPH_LIBRADOS_RADOSCLIENT_H - -#include -#include -#include - -#include -#include - -#include "common/ceph_context.h" -#include "common/ceph_mutex.h" - -#include "mon/MonClient.h" - -#include "mgr/MgrClient.h" - -#include "osdc/Objecter.h" - - - -namespace RADOS { - class RADOS; -namespace detail { - -class RADOS : public Dispatcher -{ - friend ::RADOS::RADOS; - struct MsgDeleter { - void operator()(Messenger* p) const { - if (p) { - p->shutdown(); - p->wait(); - } - delete p; - } - }; - - struct ObjDeleter { - void operator()(Objecter* p) const { - if (p) { - p->shutdown(); - } - delete p; - } - }; - - template - struct scoped_shutdown { - T& m; - scoped_shutdown(T& m) : m(m) {} - - ~scoped_shutdown() { - m.shutdown(); - } - }; - - boost::asio::io_context& ioctx; - ceph::mutex lock = ceph::make_mutex("RADOS_unleashed::_::RADOSImpl"); - int instance_id = -1; - - std::unique_ptr messenger; - - MonClient monclient; - scoped_shutdown moncsd; - - MgrClient mgrclient; - scoped_shutdown mgrcsd; - - std::unique_ptr objecter; - - -public: - - RADOS(boost::asio::io_context& ioctx, boost::intrusive_ptr cct); - ~RADOS(); - bool ms_dispatch(Message *m) override; - void ms_handle_connect(Connection *con) override; - bool ms_handle_reset(Connection *con) override; - void ms_handle_remote_reset(Connection *con) override; - bool ms_handle_refused(Connection *con) override; - mon_feature_t get_required_monitor_features() const { - return monclient.with_monmap(std::mem_fn(&MonMap::get_required_features)); - } - int get_instance_id() const { - return instance_id; - } -}; -} -} - -#endif diff --git a/src/ceph_fuse.cc b/src/ceph_fuse.cc index 4f889328f9574..5ac18116f12cd 100644 --- a/src/ceph_fuse.cc +++ b/src/ceph_fuse.cc @@ -16,9 +16,7 @@ #include #include #include -#include -#include "common/async/context_pool.h" #include "common/config.h" #include "common/errno.h" @@ -46,8 +44,6 @@ #define dout_context g_ceph_context -ceph::async::io_context_pool icp; - static void fuse_usage() { const char* argv[] = { @@ -227,8 +223,7 @@ int main(int argc, const char **argv, const char *envp[]) { int tester_r = 0; void *tester_rp = nullptr; - icp.start(cct->_conf.get_val("client_asio_thread_count")); - MonClient *mc = new MonClient(g_ceph_context, icp); + MonClient *mc = new MonClient(g_ceph_context); int r = mc->build_initial_monmap(); if (r == -EINVAL) { cerr << "failed to generate initial mon list" << std::endl; @@ -243,7 +238,7 @@ int main(int argc, const char **argv, const char *envp[]) { messenger->set_policy(entity_name_t::TYPE_MDS, Messenger::Policy::lossless_client(0)); - client = new StandaloneClient(messenger, mc, icp); + client = new StandaloneClient(messenger, mc); if (filer_flags) { client->set_filer_flags(filer_flags); } @@ -310,7 +305,6 @@ int main(int argc, const char **argv, const char *envp[]) { client->unmount(); cfuse->finalize(); out_shutdown: - icp.stop(); client->shutdown(); out_init_failed: unregister_async_signal_handler(SIGHUP, sighup_handler); diff --git a/src/ceph_mds.cc b/src/ceph_mds.cc index 4e6714ac44e48..38e673755a95a 100644 --- a/src/ceph_mds.cc +++ b/src/ceph_mds.cc @@ -20,7 +20,6 @@ #include #include -#include "common/async/context_pool.h" #include "include/ceph_features.h" #include "include/compat.h" #include "include/random.h" @@ -177,8 +176,7 @@ int main(int argc, const char **argv) register_async_signal_handler(SIGHUP, sighup_handler); // get monmap - ceph::async::io_context_pool ctxpool(2); - MonClient mc(g_ceph_context, ctxpool); + MonClient mc(g_ceph_context); if (mc.build_initial_monmap() < 0) forker.exit(1); global_init_chdir(g_ceph_context); @@ -186,7 +184,7 @@ int main(int argc, const char **argv) msgr->start(); // start mds - mds = new MDSDaemon(g_conf()->name.get_id().c_str(), msgr, &mc, ctxpool); + mds = new MDSDaemon(g_conf()->name.get_id().c_str(), msgr, &mc); // in case we have to respawn... mds->orig_argc = argc; @@ -217,7 +215,6 @@ int main(int argc, const char **argv) shutdown_async_signal_handler(); shutdown: - ctxpool.stop(); // yuck: grab the mds lock, so we can be sure that whoever in *mds // called shutdown finishes what they were doing. mds->mds_lock.lock(); @@ -241,3 +238,4 @@ int main(int argc, const char **argv) return 0; } + diff --git a/src/ceph_osd.cc b/src/ceph_osd.cc index 18101dee1221b..3e03e8632396e 100644 --- a/src/ceph_osd.cc +++ b/src/ceph_osd.cc @@ -664,10 +664,7 @@ flushjournal_out: srand(time(NULL) + getpid()); - ceph::async::io_context_pool poolctx( - cct->_conf.get_val("osd_asio_thread_count")); - - MonClient mc(g_ceph_context, poolctx); + MonClient mc(g_ceph_context); if (mc.build_initial_monmap() < 0) return -1; global_init_chdir(g_ceph_context); @@ -688,8 +685,7 @@ flushjournal_out: ms_objecter, &mc, data_path, - journal_path, - poolctx); + journal_path); int err = osdptr->pre_init(); if (err < 0) { @@ -744,7 +740,6 @@ flushjournal_out: shutdown_async_signal_handler(); // done - poolctx.stop(); delete osdptr; delete ms_public; delete ms_hb_front_client; diff --git a/src/ceph_syn.cc b/src/ceph_syn.cc index 165ea42308ac6..50e26f2815a00 100644 --- a/src/ceph_syn.cc +++ b/src/ceph_syn.cc @@ -18,7 +18,6 @@ #include "common/config.h" -#include "common/async/context_pool.h" #include "client/SyntheticClient.h" #include "client/Client.h" @@ -51,8 +50,7 @@ int main(int argc, const char **argv, char *envp[]) pick_addresses(g_ceph_context, CEPH_PICK_ADDRESS_PUBLIC); // get monmap - ceph::async::io_context_pool poolctx(1); - MonClient mc(g_ceph_context, poolctx); + MonClient mc(g_ceph_context); if (mc.build_initial_monmap() < 0) return -1; @@ -66,9 +64,9 @@ int main(int argc, const char **argv, char *envp[]) messengers[i] = Messenger::create_client_messenger(g_ceph_context, "synclient"); messengers[i]->bind(g_conf()->public_addr); - mclients[i] = new MonClient(g_ceph_context, poolctx); + mclients[i] = new MonClient(g_ceph_context); mclients[i]->build_initial_monmap(); - auto client = new StandaloneClient(messengers[i], mclients[i], poolctx); + auto client = new StandaloneClient(messengers[i], mclients[i]); client->set_filer_flags(syn_filer_flags); SyntheticClient *syn = new SyntheticClient(client); clients.push_back(client); @@ -81,8 +79,6 @@ int main(int argc, const char **argv, char *envp[]) ++p) (*p)->start_thread(); - poolctx.stop(); - //cout << "waiting for client(s) to finish" << std::endl; while (!clients.empty()) { Client *client = clients.front(); @@ -103,3 +99,4 @@ int main(int argc, const char **argv, char *envp[]) } return 0; } + diff --git a/src/client/Client.cc b/src/client/Client.cc index a9528891fa8e6..e042539c3b52e 100644 --- a/src/client/Client.cc +++ b/src/client/Client.cc @@ -29,8 +29,6 @@ #include #include -#include "common/async/waiter.h" - #if defined(__FreeBSD__) #define XATTR_CREATE 0x1 #define XATTR_REPLACE 0x2 @@ -46,7 +44,6 @@ #include "common/config.h" #include "common/version.h" -#include "common/async/waiter.h" #include "mon/MonClient.h" @@ -127,9 +124,6 @@ #define DEBUG_GETATTR_CAPS (CEPH_CAP_XATTR_SHARED) -namespace bs = boost::system; -using ceph::async::waiter; - void client_flush_set_callback(void *p, ObjectCacher::ObjectSet *oset) { Client *client = static_cast(p); @@ -5649,22 +5643,22 @@ int Client::authenticate() int Client::fetch_fsmap(bool user) { + int r; // Retrieve FSMap to enable looking up daemon addresses. We need FSMap // rather than MDSMap because no one MDSMap contains all the daemons, and // a `tell` can address any daemon. version_t fsmap_latest; - boost::system::error_code ec; do { - waiter w; - monclient->get_version("fsmap", w); + C_SaferCond cond; + monclient->get_version("fsmap", &fsmap_latest, NULL, &cond); client_lock.unlock(); - std::tie(ec, fsmap_latest, std::ignore) = w.wait(); + r = cond.wait(); client_lock.lock(); - } while (ec == boost::system::errc::resource_unavailable_try_again); + } while (r == -EAGAIN); - if (ec) { - lderr(cct) << "Failed to learn FSMap version: " << ec << dendl; - return ceph::from_error_code(ec); + if (r < 0) { + lderr(cct) << "Failed to learn FSMap version: " << cpp_strerror(r) << dendl; + return r; } ldout(cct, 10) << __func__ << " learned FSMap version " << fsmap_latest << dendl; @@ -11604,9 +11598,9 @@ void Client::_setxattr_maybe_wait_for_osdmap(const char *name, const void *value }); if (r == -ENOENT) { - waiter w; - objecter->wait_for_latest_osdmap(w); - w.wait(); + C_SaferCond ctx; + objecter->wait_for_latest_osdmap(&ctx); + ctx.wait(); } } } @@ -14205,7 +14199,7 @@ int Client::check_pool_perm(Inode *in, int need) C_SaferCond rd_cond; ObjectOperation rd_op; - rd_op.stat(nullptr, nullptr, nullptr); + rd_op.stat(NULL, (ceph::real_time*)nullptr, NULL); objecter->mutate(oid, OSDMap::file_to_object_locator(in->layout), rd_op, nullsnapc, ceph::real_clock::now(), 0, &rd_cond); @@ -14392,7 +14386,7 @@ void Client::set_session_timeout(unsigned timeout) int Client::start_reclaim(const std::string& uuid, unsigned flags, const std::string& fs_name) { - std::unique_lock l(client_lock); + std::lock_guard l(client_lock); if (!initialized) return -ENOTCONN; @@ -14468,15 +14462,13 @@ int Client::start_reclaim(const std::string& uuid, unsigned flags, // use blacklist to check if target session was killed // (config option mds_session_blacklist_on_evict needs to be true) - ldout(cct, 10) << __func__ << ": waiting for OSD epoch " << reclaim_osd_epoch << dendl; - waiter w; - objecter->wait_for_map(reclaim_osd_epoch, w); - l.unlock(); - auto ec = w.wait(); - l.lock(); - - if (ec) - return ceph::from_error_code(ec); + C_SaferCond cond; + if (!objecter->wait_for_map(reclaim_osd_epoch, &cond)) { + ldout(cct, 10) << __func__ << ": waiting for OSD epoch " << reclaim_osd_epoch << dendl; + client_lock.unlock(); + cond.wait(); + client_lock.lock(); + } bool blacklisted = objecter->with_osdmap( [this](const OSDMap &osd_map) -> bool { @@ -14600,9 +14592,8 @@ mds_rank_t Client::_get_random_up_mds() const } -StandaloneClient::StandaloneClient(Messenger *m, MonClient *mc, - boost::asio::io_context& ictx) - : Client(m, mc, new Objecter(m->cct, m, mc, ictx, 0, 0)) +StandaloneClient::StandaloneClient(Messenger *m, MonClient *mc) + : Client(m, mc, new Objecter(m->cct, m, mc, NULL, 0, 0)) { monclient->set_messenger(m); objecter->set_client_incarnation(0); diff --git a/src/client/Client.h b/src/client/Client.h index b75aa47fc1c6e..a88abb5d86e84 100644 --- a/src/client/Client.h +++ b/src/client/Client.h @@ -1305,7 +1305,7 @@ private: class StandaloneClient : public Client { public: - StandaloneClient(Messenger *m, MonClient *mc, boost::asio::io_context& ictx); + StandaloneClient(Messenger *m, MonClient *mc); ~StandaloneClient() override; diff --git a/src/cls/rgw/cls_rgw_types.h b/src/cls/rgw/cls_rgw_types.h index 1f519acb75189..2b2907ba6fab0 100644 --- a/src/cls/rgw/cls_rgw_types.h +++ b/src/cls/rgw/cls_rgw_types.h @@ -242,7 +242,7 @@ void decode_packed_val(T& val, bufferlist::const_iterator& bl) } break; default: - throw buffer::malformed_input(); + throw buffer::error(); } } diff --git a/src/common/async/context_pool.h b/src/common/async/context_pool.h deleted file mode 100644 index 2e90ba95a25a3..0000000000000 --- a/src/common/async/context_pool.h +++ /dev/null @@ -1,97 +0,0 @@ -// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- -// vim: ts=8 sw=2 smarttab -/* - * Ceph - scalable distributed file system - * - * Copyright (C) 2018 Red Hat - * Author: Adam C. Emerson - * - * This is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License version 2.1, as published by the Free Software - * Foundation. See file COPYING. - * - */ - -#ifndef CEPH_COMMON_ASYNC_CONTEXT_POOL_H -#define CEPH_COMMON_ASYNC_CONTEXT_POOL_H - -#include -#include -#include -#include -#include -#include - -#include -#include - -#include "common/ceph_mutex.h" - -namespace ceph::async { -class io_context_pool { - std::vector threadvec; - boost::asio::io_context ioctx; - std::optional> guard; - ceph::mutex m = make_mutex("ceph::io_context_pool::m"); - - void cleanup() noexcept { - guard = std::nullopt; - for (auto& th : threadvec) { - th.join(); - } - threadvec.clear(); - } -public: - io_context_pool() noexcept {} - io_context_pool(std::int16_t threadcnt) noexcept { - start(threadcnt); - } - ~io_context_pool() { - stop(); - } - void start(std::int16_t threadcnt) noexcept { - auto l = std::scoped_lock(m); - if (threadvec.empty()) { - guard.emplace(boost::asio::make_work_guard(ioctx)); - ioctx.restart(); - for (std::int16_t i = 0; i < threadcnt; ++i) { - // Mark this function as noexcept so any uncaught exceptions - // call terminate at point of throw. Otherwise, under - // libstdc++, they get caught by the thread cancellation - // infrastructure, unwinding the stack and making debugging - // much more difficult. - threadvec.emplace_back([this]() noexcept { - ioctx.run(); - }); - } - } - } - void finish() noexcept { - auto l = std::scoped_lock(m); - if (!threadvec.empty()) { - cleanup(); - } - } - void stop() noexcept { - auto l = std::scoped_lock(m); - if (!threadvec.empty()) { - ioctx.stop(); - cleanup(); - } - } - - boost::asio::io_context& get_io_context() { - return ioctx; - } - operator boost::asio::io_context&() { - return ioctx; - } - boost::asio::io_context::executor_type get_executor() { - return ioctx.get_executor(); - } -}; -} - -#endif // CEPH_COMMON_ASYNC_CONTEXT_POOL_H diff --git a/src/common/async/waiter.h b/src/common/async/waiter.h deleted file mode 100644 index 1e95d007c4362..0000000000000 --- a/src/common/async/waiter.h +++ /dev/null @@ -1,257 +0,0 @@ -// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- -// vim: ts=8 sw=2 smarttab -/* - * Ceph - scalable distributed file system - * - * Copyright (C) 2004-2006 Sage Weil - * - * This is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License version 2.1, as published by the Free Software - * Foundation. See file COPYING. - * - */ - -#ifndef CEPH_COMMON_WAITER_H -#define CEPH_COMMON_WAITER_H - -#include -#include - -#include - -#include "include/ceph_assert.h" -#include "include/function2.hpp" - -#include "common/ceph_mutex.h" - -namespace ceph::async { -namespace detail { -// For safety reasons (avoiding undefined behavior around sequence -// points) std::reference_wrapper disallows move construction. This -// harms us in cases where we want to pass a reference in to something -// that unavoidably moves. -// -// It should not be used generally. -template -class rvalue_reference_wrapper { -public: - // types - using type = T; - - rvalue_reference_wrapper(T& r) noexcept - : p(std::addressof(r)) {} - - // We write our semantics to match those of reference collapsing. If - // we're treated as an lvalue, collapse to one. - - rvalue_reference_wrapper(const rvalue_reference_wrapper&) noexcept = default; - rvalue_reference_wrapper(rvalue_reference_wrapper&&) noexcept = default; - - // assignment - rvalue_reference_wrapper& operator=( - const rvalue_reference_wrapper& x) noexcept = default; - rvalue_reference_wrapper& operator=( - rvalue_reference_wrapper&& x) noexcept = default; - - operator T& () const noexcept { - return *p; - } - T& get() const noexcept { - return *p; - } - - operator T&& () noexcept { - return std::move(*p); - } - T&& get() noexcept { - return std::move(*p); - } - - template - std::result_of_t operator ()(Args&&... args ) const { - return (*p)(std::forward(args)...); - } - - template - std::result_of_t operator ()(Args&&... args ) { - return std::move(*p)(std::forward(args)...); - } - -private: - T* p; -}; - -class base { -protected: - ceph::mutex lock = ceph::make_mutex("ceph::async::detail::base::lock"); - ceph::condition_variable cond; - bool has_value = false; - - ~base() = default; - - auto wait_base() { - std::unique_lock l(lock); - cond.wait(l, [this](){ return has_value; }); - return l; - } - - auto exec_base() { - std::unique_lock l(lock); - // There's no really good way to handle being called twice - // without being reset. - ceph_assert(!has_value); - has_value = true; - cond.notify_one(); - return l; - } -}; -} - -// waiter is a replacement for C_SafeCond and friends. It is the -// moral equivalent of a future but plays well with a world of -// callbacks. -template -class waiter; - -template<> -class waiter<> final : public detail::base { -public: - void wait() { - wait_base(); - has_value = false; - } - - void operator()() { - exec_base(); - } - - auto ref() { - return detail::rvalue_reference_wrapper(*this); - } - - - operator fu2::unique_function() { - return fu2::unique_function(ref()); - } -}; - -template -class waiter final : public detail::base { - std::aligned_storage_t ret; - -public: - Ret wait() { - auto l = wait_base(); - auto r = reinterpret_cast(&ret); - auto t = std::move(*r); - r->~Ret(); - has_value = false; - return t; - } - - void operator()(Ret&& _ret) { - auto l = exec_base(); - auto r = reinterpret_cast(&ret); - *r = std::move(_ret); - } - - void operator()(const Ret& _ret) { - auto l = exec_base(); - auto r = reinterpret_cast(&ret); - *r = std::move(_ret); - } - - auto ref() { - return detail::rvalue_reference_wrapper(*this); - } - - operator fu2::unique_function() { - return fu2::unique_function(ref()); - } - - ~waiter() { - if (has_value) - reinterpret_cast(&ret)->~Ret(); - } -}; - -template -class waiter final : public detail::base { - std::tuple ret; - -public: - std::tuple wait() { - using std::tuple; - auto l = wait_base(); - return std::move(ret); - auto r = reinterpret_cast*>(&ret); - auto t = std::move(*r); - r->~tuple(); - has_value = false; - return t; - } - - void operator()(Ret&&... _ret) { - auto l = exec_base(); - auto r = reinterpret_cast*>(&ret); - *r = std::forward_as_tuple(_ret...); - } - - void operator()(const Ret&... _ret) { - auto l = exec_base(); - auto r = reinterpret_cast*>(&ret); - *r = std::forward_as_tuple(_ret...); - } - - auto ref() { - return detail::rvalue_reference_wrapper(*this); - } - - operator fu2::unique_function() { - return fu2::unique_function(ref()); - } - - ~waiter() { - using std::tuple; - if (has_value) - reinterpret_cast*>(&ret)->~tuple(); - } -}; -} - -namespace boost::asio { -template -class async_result, void(S...)> { -public: - using completion_handler_type = - ceph::async::detail::rvalue_reference_wrapper>; - - using return_type = void; - - explicit async_result(completion_handler_type& h) {} - - return_type get() {} - - async_result(const async_result&) = delete; - async_result& operator=(const async_result&) = delete; -}; - -template -struct async_completion, void(S...)> { - using completion_handler_type = - typename boost::asio::async_result, - void(S...)>::completion_handler_type; - - explicit async_completion(ceph::async::waiter& w) - : completion_handler(ceph::async::detail::rvalue_reference_wrapper(w)), - result(completion_handler){} - - completion_handler_type completion_handler; - - /// The result of the asynchronous operation's initiating function. - async_result, void(S...)> result; -}; -} - -#endif // CEPH_COMMON_WAITER_H diff --git a/src/common/buffer.cc b/src/common/buffer.cc index 9ea83101826a5..b7d3591600a50 100644 --- a/src/common/buffer.cc +++ b/src/common/buffer.cc @@ -33,7 +33,6 @@ #include "common/valgrind.h" #include "common/deleter.h" #include "common/RWLock.h" -#include "common/error_code.h" #include "include/spinlock.h" #include "include/scope_guard.h" @@ -71,6 +70,21 @@ static ceph::spinlock debug_lock; return buffer_missed_crc; } + const char * buffer::error::what() const throw () { + return "buffer::exception"; + } + const char * buffer::bad_alloc::what() const throw () { + return "buffer::bad_alloc"; + } + const char * buffer::end_of_buffer::what() const throw () { + return "buffer::end_of_buffer"; + } + const char * buffer::malformed_input::what() const throw () { + return buf; + } + buffer::error_code::error_code(int error) : + buffer::malformed_input(cpp_strerror(error).c_str()), code(error) {} + /* * raw_combined is always placed within a single allocation along * with the data buffer. the data goes at the beginning, and @@ -2252,6 +2266,11 @@ std::ostream& buffer::operator<<(std::ostream& out, const buffer::list& bl) { return out; } +std::ostream& buffer::operator<<(std::ostream& out, const buffer::error& e) +{ + return out << e.what(); +} + MEMPOOL_DEFINE_OBJECT_FACTORY(buffer::raw_malloc, buffer_raw_malloc, buffer_meta); MEMPOOL_DEFINE_OBJECT_FACTORY(buffer::raw_posix_aligned, @@ -2264,81 +2283,3 @@ MEMPOOL_DEFINE_OBJECT_FACTORY(buffer::raw_unshareable, buffer_raw_unshareable, MEMPOOL_DEFINE_OBJECT_FACTORY(buffer::raw_static, buffer_raw_static, buffer_meta); - -namespace ceph::buffer { -inline namespace v14_2_0 { - -class buffer_error_category : public ceph::converting_category { -public: - buffer_error_category(){} - const char* name() const noexcept override; - std::string message(int ev) const override; - boost::system::error_condition default_error_condition(int ev) const noexcept - override; - using ceph::converting_category::equivalent; - bool equivalent(int ev, const boost::system::error_condition& c) const - noexcept override; - int from_code(int ev) const noexcept override; -}; - -const char* buffer_error_category::name() const noexcept { - return "buffer"; -} - -std::string buffer_error_category::message(int ev) const { - using ceph::buffer::errc; - if (ev == 0) - return "No error"; - - switch (static_cast(ev)) { - case errc::bad_alloc: - return "Bad allocation"; - - case errc::end_of_buffer: - return "End of buffer"; - - case errc::malformed_input: - return "Malformed input"; - } - - return "Unknown error"; -} - -boost::system::error_condition -buffer_error_category::default_error_condition(int ev)const noexcept { - using ceph::buffer::errc; - switch (static_cast(ev)) { - case errc::bad_alloc: - return boost::system::errc::not_enough_memory; - case errc::end_of_buffer: - case errc::malformed_input: - return boost::system::errc::io_error; - } - return { ev, *this }; -} - -bool buffer_error_category::equivalent(int ev, const boost::system::error_condition& c) const noexcept { - return default_error_condition(ev) == c; -} - -int buffer_error_category::from_code(int ev) const noexcept { - using ceph::buffer::errc; - switch (static_cast(ev)) { - case errc::bad_alloc: - return -ENOMEM; - - case errc::end_of_buffer: - return -EIO; - - case errc::malformed_input: - return -EIO; - } - return -EDOM; -} - -const boost::system::error_category& buffer_category() noexcept { - static const buffer_error_category c; - return c; -} -} -} diff --git a/src/common/ceph_context.h b/src/common/ceph_context.h index ae590865945c5..6b6e9482b997e 100644 --- a/src/common/ceph_context.h +++ b/src/common/ceph_context.h @@ -25,8 +25,6 @@ #include #include -#include - #include "include/any.h" #include "common/cmdparse.h" @@ -365,15 +363,4 @@ private: }; #endif // WITH_SEASTAR -inline void intrusive_ptr_add_ref(CephContext* cct) -{ - cct->get(); -} - -inline void intrusive_ptr_release(CephContext* cct) -{ - cct->put(); -} - - #endif diff --git a/src/common/ceph_time.h b/src/common/ceph_time.h index a2018703a2774..ae4a17c781296 100644 --- a/src/common/ceph_time.h +++ b/src/common/ceph_time.h @@ -18,7 +18,6 @@ #include #include #include -#include #include #include "include/ceph_assert.h" @@ -435,9 +434,6 @@ namespace ceph { return std::chrono::duration_cast( std::chrono::duration(d)); } - inline std::optional maybe_timespan(const double d) { - return d ? std::make_optional(make_timespan(d)) : std::nullopt; - } } std::ostream& operator<<(std::ostream& m, const timespan& t); diff --git a/src/common/ceph_timer.h b/src/common/ceph_timer.h index 0090f7ccdfe39..b29fac9c3fcb3 100644 --- a/src/common/ceph_timer.h +++ b/src/common/ceph_timer.h @@ -19,9 +19,14 @@ #include #include -#include "common/detail/construct_suspended.h" - namespace ceph { + + /// Newly constructed timer should be suspended at point of + /// construction. + + struct construct_suspended_t { }; + constexpr construct_suspended_t construct_suspended { }; + namespace timer_detail { using boost::intrusive::member_hook; using boost::intrusive::set_member_hook; diff --git a/src/common/config.cc b/src/common/config.cc index 4c2af4ce6044c..0259ef2f8ee22 100644 --- a/src/common/config.cc +++ b/src/common/config.cc @@ -1306,7 +1306,7 @@ void md_config_t::_get_my_sections(const ConfigValues& values, { sections.push_back(values.name.to_str()); - sections.push_back(values.name.get_type_name().data()); + sections.push_back(values.name.get_type_name()); sections.push_back("global"); } diff --git a/src/common/detail/construct_suspended.h b/src/common/detail/construct_suspended.h deleted file mode 100644 index 521bda0f833d0..0000000000000 --- a/src/common/detail/construct_suspended.h +++ /dev/null @@ -1,24 +0,0 @@ -// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- -// vim: ts=8 sw=2 smarttab -/* - * Ceph - scalable distributed file system - * - * Copyright (C) 2018 Red Hat - * Author: Adam C. Emerson - * - * This is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License version 2.1, as published by the Free Software - * Foundation. See file COPYING. - * - */ - -#ifndef CEPH_COMMON_DETAIL_CONSTRUCT_SUSPENDED_H -#define CEPH_COMMON_DETAIL_CONSTRUCT_SUSPENDED_H - -namespace ceph { - struct construct_suspended_t { }; - inline constexpr construct_suspended_t construct_suspended { }; -} - -#endif // CEPH_COMMON_DETAIL_CONSTRUCT_SUSPENDED_H diff --git a/src/common/entity_name.cc b/src/common/entity_name.cc index 2eb24829a1c86..37d02bd94df46 100644 --- a/src/common/entity_name.cc +++ b/src/common/entity_name.cc @@ -42,22 +42,22 @@ to_cstr() const } bool EntityName:: -from_str(std::string_view s) +from_str(const string& s) { size_t pos = s.find('.'); if (pos == string::npos) return false; - - auto type_ = s.substr(0, pos); - auto id_ = s.substr(pos + 1); + + string type_ = s.substr(0, pos); + string id_ = s.substr(pos + 1); if (set(type_, id_)) return false; return true; } void EntityName:: -set(uint32_t type_, std::string_view id_) +set(uint32_t type_, const std::string &id_) { type = type_; id = id_; @@ -72,9 +72,9 @@ set(uint32_t type_, std::string_view id_) } int EntityName:: -set(std::string_view type_, std::string_view id_) +set(const std::string &type_, const std::string &id_) { - uint32_t t = str_to_ceph_entity_type(type_); + uint32_t t = str_to_ceph_entity_type(type_.c_str()); if (t == CEPH_ENTITY_TYPE_ANY) return -EINVAL; set(t, id_); @@ -88,13 +88,13 @@ set_type(uint32_t type_) } int EntityName:: -set_type(std::string_view type_) +set_type(const char *type_) { return set(type_, id); } void EntityName:: -set_id(std::string_view id_) +set_id(const std::string &id_) { set(type, id_); } @@ -106,13 +106,13 @@ void EntityName::set_name(entity_name_t n) set(n.type(), s); } -std::string_view EntityName:: +const char* EntityName:: get_type_str() const { return ceph_entity_type_name(type); } -std::string_view EntityName:: +const char *EntityName:: get_type_name() const { return ceph_entity_type_name(type); diff --git a/src/common/entity_name.h b/src/common/entity_name.h index 886c4b4946f8e..1dd56f66d740a 100644 --- a/src/common/entity_name.h +++ b/src/common/entity_name.h @@ -15,8 +15,6 @@ #ifndef CEPH_COMMON_ENTITY_NAME_H #define CEPH_COMMON_ENTITY_NAME_H -#include - #include #include "msg/msg_types.h" @@ -44,15 +42,15 @@ struct EntityName const std::string& to_str() const; const char *to_cstr() const; - bool from_str(std::string_view s); - void set(uint32_t type_, std::string_view id_); - int set(std::string_view type_, std::string_view id_); + bool from_str(const std::string& s); + void set(uint32_t type_, const std::string &id_); + int set(const std::string &type_, const std::string &id_); void set_type(uint32_t type_); - int set_type(std::string_view type); - void set_id(std::string_view id_); + int set_type(const char *type); + void set_id(const std::string &id_); void set_name(entity_name_t n); - std::string_view get_type_str() const; + const char* get_type_str() const; uint32_t get_type() const { return type; } bool is_osd() const { return get_type() == CEPH_ENTITY_TYPE_OSD; } @@ -61,7 +59,7 @@ struct EntityName bool is_client() const { return get_type() == CEPH_ENTITY_TYPE_CLIENT; } bool is_mon() const { return get_type() == CEPH_ENTITY_TYPE_MON; } - std::string_view get_type_name() const; + const char * get_type_name() const; const std::string &get_id() const; bool has_default_id() const; diff --git a/src/common/error_code.cc b/src/common/error_code.cc deleted file mode 100644 index 52eee7f1b5e4b..0000000000000 --- a/src/common/error_code.cc +++ /dev/null @@ -1,182 +0,0 @@ -// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- -// vim: ts=8 sw=2 smarttab -/* - * Ceph - scalable distributed file system - * - * Copyright (C) 2017 Red Hat, Inc. - * - * Author: Adam C. Emerson - * - * This is free software; you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License version - * 2.1, as published by the Free Software Foundation. See file - * COPYING. - */ - -#include - -#include "common/error_code.h" - -using boost::system::error_category; -using boost::system::error_condition; -using boost::system::generic_category; -using boost::system::system_category; - -namespace ceph { - -// A category for error conditions particular to Ceph - -class ceph_error_category : public converting_category { -public: - ceph_error_category(){} - const char* name() const noexcept override; - std::string message(int ev) const override; - using converting_category::equivalent; - bool equivalent(const boost::system::error_code& c, - int ev) const noexcept override; - int from_code(int ev) const noexcept override; -}; - -const char* ceph_error_category::name() const noexcept { - return "ceph"; -} - -std::string ceph_error_category::message(int ev) const { - if (ev == 0) - return "No error"; - - switch (static_cast(ev)) { - - case errc::not_in_map: - return "Map does not contain requested entry."; - case errc::does_not_exist: - return "Item does not exist"; - case errc::failure: - return "An internal fault or inconsistency occurred"; - case errc::exists: - return "Already exists"; - case errc::limit_exceeded: - return "Attempt to use too much"; - case errc::auth: - return "Authentication error"; - case errc::conflict: - return "Conflict detected or precondition failed"; - } - - return "Unknown error."; -} - -bool ceph_error_category::equivalent(const boost::system::error_code& c, - int ev) const noexcept { - if (c.category() == system_category()) { - if (c.value() == boost::system::errc::no_such_file_or_directory) { - if (ev == static_cast(errc::not_in_map) || - ev == static_cast(errc::does_not_exist)) { - // Blargh. A bunch of stuff returns ENOENT now, so just to be safe. - return true; - } - } - if (c.value() == boost::system::errc::io_error) { - if (ev == static_cast(errc::failure)) { - return true; - } - } - if (c.value() == boost::system::errc::file_exists) { - if (ev == static_cast(errc::exists)) { - return true; - } - } - if (c.value() == boost::system::errc::no_space_on_device || - c.value() == boost::system::errc::invalid_argument) { - if (ev == static_cast(errc::limit_exceeded)) { - return true; - } - } - if (c.value() == boost::system::errc::operation_not_permitted) { - if (ev == static_cast(ceph::errc::conflict)) { - return true; - } - } - } - return false; -} - -int ceph_error_category::from_code(int ev) const noexcept { - if (ev == 0) - return 0; - - switch (static_cast(ev)) { - case errc::not_in_map: - case errc::does_not_exist: - // What we use now. - return -ENOENT; - case errc::failure: - return -EIO; - case errc::exists: - return -EEXIST; - case errc::limit_exceeded: - return -EIO; - case errc::auth: - return -EACCES; - case errc::conflict: - return -EINVAL; - } - return -EDOM; -} - -const error_category& ceph_category() noexcept { - static const ceph_error_category c; - return c; -} - - -// This is part of the glue for hooking new code to old. Since -// Context* and other things give us integer codes from errno, wrap -// them in an error_code. -boost::system::error_code to_error_code(int ret) noexcept -{ - if (ret == 0) - return {}; - return { std::abs(ret), boost::system::system_category() }; -} - -// This is more complicated. For the case of categories defined -// elsewhere, we have to convert everything here. -int from_error_code(boost::system::error_code e) noexcept -{ - if (!e) - return 0; - - auto c = dynamic_cast(&e.category()); - // For categories we define - if (c) - return c->from_code(e.value()); - - // For categories matching values of errno - if (e.category() == boost::system::system_category() || - e.category() == boost::system::generic_category() || - // ASIO uses the system category for these and matches system - // error values. - e.category() == boost::asio::error::get_netdb_category() || - e.category() == boost::asio::error::get_addrinfo_category()) - return -e.value(); - - if (e.category() == boost::asio::error::get_misc_category()) { - // These values are specific to asio - switch (e.value()) { - case boost::asio::error::already_open: - return -EIO; - case boost::asio::error::eof: - return -EIO; - case boost::asio::error::not_found: - return -ENOENT; - case boost::asio::error::fd_set_failure: - return -EINVAL; - } - } - // Add any other categories we use here. - - // Marcus likes this as a sentinel for 'Error code? What error code?' - return -EDOM; -} -} diff --git a/src/common/error_code.h b/src/common/error_code.h deleted file mode 100644 index 2fc7cdd377c27..0000000000000 --- a/src/common/error_code.h +++ /dev/null @@ -1,75 +0,0 @@ -// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- -// vim: ts=8 sw=2 smarttab -/* - * Ceph - scalable distributed file system - * - * Copyright (C) 2017 Red Hat, Inc. - * - * Author: Adam C. Emerson - * - * This is free software; you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License version - * 2.1, as published by the Free Software Foundation. See file - * COPYING. - */ - -#ifndef COMMON_CEPH_ERROR_CODE -#define COMMON_CEPH_ERROR_CODE - -#include - -#include -#include - -namespace ceph { - -// This is for error categories we define, so we can specify the -// equivalent integral value at the point of definition. -class converting_category : public boost::system::error_category { -public: - virtual int from_code(int code) const noexcept = 0; -}; - -const boost::system::error_category& ceph_category() noexcept; - -enum class errc { - not_in_map = 1, // The requested item was not found in the map - does_not_exist, // Item does not exist - failure, // An internal fault or inconsistency - exists, // Already exists - limit_exceeded, // Attempting to use too much of something - auth, // May not be an auth failure. It could be that the - // preconditions to attempt auth failed. - conflict, // Conflict or precondition failure -}; -} - -namespace boost { -namespace system { -template<> -struct is_error_condition_enum<::ceph::errc> { - static const bool value = true; -}; -template<> -struct is_error_code_enum<::ceph::errc> { - static const bool value = false; -}; -} -} - -namespace ceph { -// explicit conversion: -inline boost::system::error_code make_error_code(errc e) noexcept { - return { static_cast(e), ceph_category() }; -} - -// implicit conversion: -inline boost::system::error_condition make_error_condition(errc e) noexcept { - return { static_cast(e), ceph_category() }; -} - -boost::system::error_code to_error_code(int ret) noexcept; -int from_error_code(boost::system::error_code e) noexcept; -} - -#endif // COMMON_CEPH_ERROR_CODE diff --git a/src/common/options.cc b/src/common/options.cc index 7f65b8bd048d6..ddfef20fce211 100644 --- a/src/common/options.cc +++ b/src/common/options.cc @@ -5246,18 +5246,6 @@ std::vector