]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
neorados: More snapshot support
authorAdam Emerson <aemerson@redhat.com>
Tue, 29 Aug 2023 22:13:55 +0000 (18:13 -0400)
committerAdam Emerson <aemerson@redhat.com>
Thu, 7 Dec 2023 21:26:58 +0000 (16:26 -0500)
Signed-off-by: Adam Emerson <aemerson@redhat.com>
src/include/neorados/RADOS.hpp
src/neorados/RADOS.cc

index e89c7d02e41af2911e707584d8030936e56d7270..ab95bdb17993ce631c5405c7dc56ab30fba27eac 100644 (file)
@@ -120,6 +120,9 @@ private:
   std::aligned_storage_t<impl_size> 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<boost::asio::completion_token_for<SimpleOpSig> 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<CompletionToken>(token));
+  }
+
   using SMSnapSig = void(boost::system::error_code, std::uint64_t);
   using SMSnapComp = boost::asio::any_completion_handler<SMSnapSig>;
   template<boost::asio::completion_token_for<SMSnapSig> CompletionToken>
@@ -1458,7 +1468,7 @@ public:
        boost::asio::get_associated_executor(token, get_executor())));
     return boost::asio::async_initiate<decltype(consigned), SMSnapSig>(
       [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<std::uint64_t> list_snaps(std::int64_t pool) const;
+  std::vector<std::uint64_t> list_snaps(std::string_view pool) const;
+  std::vector<std::uint64_t> 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<boost::asio::completion_token_for<SimpleOpSig> CompletionToken>
   auto create_pool(std::string name, std::optional<int> crush_rule,
                   CompletionToken&& token) {
@@ -1840,6 +1883,7 @@ private:
 
 enum class errc {
   pool_dne = 1,
+  snap_dne,
   invalid_snapcontext
 };
 
index d8d1abbe2973a4613add6c2eb0b972b17f036885..9a71b1269a161d3e2802f4d397eb9dbf20fa4e4d 100644 (file)
@@ -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<std::uint64_t> 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<std::uint64_t> snaps;
+    for (const auto& [snapid, snapinfo] : pgpool->snaps) {
+      snaps.push_back(snapid);
+    }
+    return snaps;
+  });
+}
+
+std::vector<std::uint64_t> 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<std::uint64_t> 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<int> crush_rule,
                         SimpleOpComp c)
@@ -1604,7 +1755,8 @@ const char* category::message(int ev, char*,
   switch (static_cast<errc>(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<errc>(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<errc>(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<errc>(ev)) {
   case errc::pool_dne:
     return -ENOENT;
+  case errc::snap_dne:
+    return -ENOENT;
   case errc::invalid_snapcontext:
     return -EINVAL;
   }