From: Adam Emerson Date: Tue, 29 Aug 2023 22:13:55 +0000 (-0400) Subject: neorados: More snapshot support X-Git-Tag: v19.3.0~349^2~7 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=ccc1b89aa98ec0ad6f9e92e238c120870c3195bf;p=ceph.git neorados: More snapshot support Signed-off-by: Adam Emerson --- diff --git a/src/include/neorados/RADOS.hpp b/src/include/neorados/RADOS.hpp index e89c7d02e41..ab95bdb1799 100644 --- a/src/include/neorados/RADOS.hpp +++ b/src/include/neorados/RADOS.hpp @@ -120,6 +120,9 @@ private: std::aligned_storage_t impl; }; +inline constexpr std::uint64_t snap_dir = -1; +inline constexpr std::uint64_t snap_head = -2; + // Not the same as the librados::IoCtx, but it does gather together // some of the same metadata. Since we're likely to do multiple // operations in the same pool or namespace, it doesn't make sense to @@ -1449,6 +1452,13 @@ public: }, consigned); } + template CompletionToken> + auto create_pool_snap(const IOContext& pool, std::string snap_name, + CompletionToken&& token) { + return create_pool_snap(pool.get_pool(), std::move(snap_name), + std::forward(token)); + } + using SMSnapSig = void(boost::system::error_code, std::uint64_t); using SMSnapComp = boost::asio::any_completion_handler; template CompletionToken> @@ -1458,7 +1468,7 @@ public: boost::asio::get_associated_executor(token, get_executor()))); return boost::asio::async_initiate( [pool, this](auto&& handler) mutable { - allocage_selfmanaged_snap_(pool, std::move(handler)); + allocate_selfmanaged_snap_(pool, std::move(handler)); }, consigned); } @@ -1487,6 +1497,39 @@ public: }, consigned); } + bool get_self_managed_snaps_mode(std::int64_t pool) const; + bool get_self_managed_snaps_mode(std::string_view pool) const; + bool get_self_managed_snaps_mode(const IOContext& pool) const { + return get_self_managed_snaps_mode(pool.get_pool()); + } + + std::vector list_snaps(std::int64_t pool) const; + std::vector list_snaps(std::string_view pool) const; + std::vector list_snaps(const IOContext& pool) const { + return list_snaps(pool.get_pool()); + } + + std::uint64_t lookup_snap(std::int64_t pool, std::string_view snap) const; + std::uint64_t lookup_snap(std::string_view pool, std::string_view snap) const; + std::uint64_t lookup_snap(const IOContext& pool, std::string_view snap) const { + return lookup_snap(pool.get_pool(), snap); + } + + std::string get_snap_name(std::int64_t pool, std::uint64_t snap) const; + std::string get_snap_name(std::string_view pool, std::uint64_t snap) const; + std::string get_snap_name(const IOContext& pool, std::uint64_t snap) const { + return get_snap_name(pool.get_pool(), snap); + } + + ceph::real_time get_snap_timestamp(std::int64_t pool, + std::uint64_t snap) const; + ceph::real_time get_snap_timestamp(std::string_view pool, + std::uint64_t snap) const; + ceph::real_time get_snap_timestamp(const IOContext& pool, + std::uint64_t snap) const { + return get_snap_timestamp(pool.get_pool(), snap); + } + template CompletionToken> auto create_pool(std::string name, std::optional crush_rule, CompletionToken&& token) { @@ -1840,6 +1883,7 @@ private: enum class errc { pool_dne = 1, + snap_dne, invalid_snapcontext }; diff --git a/src/neorados/RADOS.cc b/src/neorados/RADOS.cc index d8d1abbe297..9a71b1269a1 100644 --- a/src/neorados/RADOS.cc +++ b/src/neorados/RADOS.cc @@ -1079,6 +1079,157 @@ void RADOS::delete_selfmanaged_snap_(std::int64_t pool, })); } +bool RADOS::get_self_managed_snaps_mode(std::int64_t pool) const { + return impl->objecter->with_osdmap([pool](const OSDMap& osdmap) { + const auto pgpool = osdmap.get_pg_pool(pool); + if (!pgpool) { + throw bs::system_error(bs::error_code(errc::pool_dne)); + } + return pgpool->is_unmanaged_snaps_mode(); + }); +} + +bool RADOS::get_self_managed_snaps_mode(std::string_view pool) const { + return impl->objecter->with_osdmap([pool](const OSDMap& osdmap) { + int64_t poolid = osdmap.lookup_pg_pool_name(pool); + if (poolid < 0) { + throw bs::system_error(bs::error_code(errc::pool_dne)); + } + const auto pgpool = osdmap.get_pg_pool(poolid); + if (!pgpool) { + throw bs::system_error(bs::error_code(errc::pool_dne)); + } + return pgpool->is_unmanaged_snaps_mode(); + }); +} + +std::vector RADOS::list_snaps(std::int64_t pool) const { + return impl->objecter->with_osdmap([pool](const OSDMap& osdmap) { + const auto pgpool = osdmap.get_pg_pool(pool); + if (!pgpool) { + throw bs::system_error(bs::error_code(errc::pool_dne)); + } + std::vector snaps; + for (const auto& [snapid, snapinfo] : pgpool->snaps) { + snaps.push_back(snapid); + } + return snaps; + }); +} + +std::vector RADOS::list_snaps(std::string_view pool) const { + return impl->objecter->with_osdmap([pool](const OSDMap& osdmap) { + int64_t poolid = osdmap.lookup_pg_pool_name(pool); + if (poolid < 0) { + throw bs::system_error(bs::error_code(errc::pool_dne)); + } + const auto pgpool = osdmap.get_pg_pool(poolid); + if (!pgpool) { + throw bs::system_error(bs::error_code(errc::pool_dne)); + } + std::vector snaps; + for (const auto& [snapid, snapinfo] : pgpool->snaps) { + snaps.push_back(snapid); + } + return snaps; + }); +} + +std::uint64_t RADOS::lookup_snap(std::int64_t pool, std::string_view snap) const { + return impl->objecter->with_osdmap([pool, snap](const OSDMap& osdmap) { + const auto pgpool = osdmap.get_pg_pool(pool); + if (!pgpool) { + throw bs::system_error(bs::error_code(errc::pool_dne)); + } + for (const auto& [id, snapinfo] : pgpool->snaps) { + if (snapinfo.name == snap) return id; + } + throw bs::system_error(bs::error_code(errc::snap_dne)); + }); +} + +std::uint64_t RADOS::lookup_snap(std::string_view pool, std::string_view snap) const { + return impl->objecter->with_osdmap([pool, snap](const OSDMap& osdmap) { + int64_t poolid = osdmap.lookup_pg_pool_name(pool); + if (poolid < 0) { + throw bs::system_error(bs::error_code(errc::pool_dne)); + } + const auto pgpool = osdmap.get_pg_pool(poolid); + if (!pgpool) { + throw bs::system_error(bs::error_code(errc::pool_dne)); + } + for (const auto& [id, snapinfo] : pgpool->snaps) { + if (snapinfo.name == snap) return id; + } + throw bs::system_error(bs::error_code(errc::snap_dne)); + }); +} + +std::string RADOS::get_snap_name(std::int64_t pool, std::uint64_t snap) const { + return impl->objecter->with_osdmap([pool, snap](const OSDMap& osdmap) { + const auto pgpool = osdmap.get_pg_pool(pool); + if (!pgpool) { + throw bs::system_error(bs::error_code(errc::pool_dne)); + } + if (auto i = pgpool->snaps.find(snap); i == pgpool->snaps.cend()) { + throw bs::system_error(bs::error_code(errc::snap_dne)); + } else { + return i->second.name; + } + }); +} +std::string RADOS::get_snap_name(std::string_view pool, + std::uint64_t snap) const { + return impl->objecter->with_osdmap([pool, snap](const OSDMap& osdmap) { + int64_t poolid = osdmap.lookup_pg_pool_name(pool); + if (poolid < 0) { + throw bs::system_error(bs::error_code(errc::pool_dne)); + } + const auto pgpool = osdmap.get_pg_pool(poolid); + if (!pgpool) { + throw bs::system_error(bs::error_code(errc::pool_dne)); + } + if (auto i = pgpool->snaps.find(snap); i == pgpool->snaps.cend()) { + throw bs::system_error(bs::error_code(errc::snap_dne)); + } else { + return i->second.name; + } + }); +} + +ceph::real_time RADOS::get_snap_timestamp(std::int64_t pool, + std::uint64_t snap) const { + return impl->objecter->with_osdmap([pool, snap](const OSDMap& osdmap) { + const auto pgpool = osdmap.get_pg_pool(pool); + if (!pgpool) { + throw bs::system_error(bs::error_code(errc::pool_dne)); + } + if (auto i = pgpool->snaps.find(snap); i == pgpool->snaps.cend()) { + throw bs::system_error(bs::error_code(errc::snap_dne)); + } else { + return i->second.stamp.to_real_time(); + } + }); +} +ceph::real_time RADOS::get_snap_timestamp(std::string_view pool, + std::uint64_t snap) const { + return impl->objecter->with_osdmap([pool, snap](const OSDMap& osdmap) { + int64_t poolid = osdmap.lookup_pg_pool_name(pool); + if (poolid < 0) { + throw bs::system_error(bs::error_code(errc::pool_dne)); + } + const auto pgpool = osdmap.get_pg_pool(poolid); + if (!pgpool) { + throw bs::system_error(bs::error_code(errc::pool_dne)); + } + if (auto i = pgpool->snaps.find(snap); i == pgpool->snaps.cend()) { + throw bs::system_error(bs::error_code(errc::snap_dne)); + } else { + return i->second.stamp.to_real_time(); + } + }); +} + void RADOS::create_pool_(std::string name, std::optional crush_rule, SimpleOpComp c) @@ -1604,7 +1755,8 @@ const char* category::message(int ev, char*, switch (static_cast(ev)) { case errc::pool_dne: return "Pool does not exist"; - + case errc::snap_dne: + return "Snapshot does not exist"; case errc::invalid_snapcontext: return "Invalid snapcontext"; } @@ -1620,6 +1772,8 @@ bs::error_condition category::default_error_condition(int ev) const noexcept { switch (static_cast(ev)) { case errc::pool_dne: return ceph::errc::does_not_exist; + case errc::snap_dne: + return ceph::errc::does_not_exist; case errc::invalid_snapcontext: return bs::errc::invalid_argument; } @@ -1633,6 +1787,11 @@ bool category::equivalent(int ev, const bs::error_condition& c) const noexcept { return true; } } + if (static_cast(ev) == errc::snap_dne) { + if (c == bs::errc::no_such_file_or_directory) { + return true; + } + } return default_error_condition(ev) == c; } @@ -1641,6 +1800,8 @@ int category::from_code(int ev) const noexcept { switch (static_cast(ev)) { case errc::pool_dne: return -ENOENT; + case errc::snap_dne: + return -ENOENT; case errc::invalid_snapcontext: return -EINVAL; }