]> git.proxmox.com Git - ceph.git/blobdiff - ceph/src/librbd/Utils.cc
update source to Ceph Pacific 16.2.2
[ceph.git] / ceph / src / librbd / Utils.cc
index c9d7b0413ab776516123e2975604ac4cec125ba1..dadf6ab8126ae35c7b8afb86e9955226dcab87aa 100644 (file)
@@ -5,12 +5,18 @@
 #include <boost/lexical_cast.hpp>
 
 #include "librbd/Utils.h"
+#include "include/random.h"
 #include "include/rbd_types.h"
 #include "include/stringify.h"
+#include "include/neorados/RADOS.hpp"
 #include "include/rbd/features.h"
 #include "common/dout.h"
+#include "common/errno.h"
 #include "librbd/ImageCtx.h"
 #include "librbd/Features.h"
+
+#include <boost/algorithm/string/predicate.hpp>
+#include <bitset>
 #include <random>
 
 #define dout_subsys ceph_subsys_rbd
 
 namespace librbd {
 namespace util {
+namespace {
+
+const std::string CONFIG_KEY_URI_PREFIX{"config://"};
+
+} // anonymous namespace
 
 const std::string group_header_name(const std::string &group_id)
 {
@@ -52,7 +63,7 @@ std::string generate_image_id(librados::IoCtx &ioctx) {
   librados::Rados rados(ioctx);
 
   uint64_t bid = rados.get_instance_id();
-  std::mt19937 generator{std::random_device{}()};
+  std::mt19937 generator{random_device_t{}()};
   std::uniform_int_distribution<uint32_t> distribution{0, 0xFFFFFFFF};
   uint32_t extra = distribution(generator);
 
@@ -141,5 +152,92 @@ int create_ioctx(librados::IoCtx& src_io_ctx, const std::string& pool_desc,
   return 0;
 }
 
+int snap_create_flags_api_to_internal(CephContext *cct, uint32_t api_flags,
+                                      uint64_t *internal_flags) {
+  *internal_flags = 0;
+
+  if (api_flags & RBD_SNAP_CREATE_SKIP_QUIESCE) {
+    *internal_flags |= SNAP_CREATE_FLAG_SKIP_NOTIFY_QUIESCE;
+    api_flags &= ~RBD_SNAP_CREATE_SKIP_QUIESCE;
+  } else if (api_flags & RBD_SNAP_CREATE_IGNORE_QUIESCE_ERROR) {
+    *internal_flags |= SNAP_CREATE_FLAG_IGNORE_NOTIFY_QUIESCE_ERROR;
+    api_flags &= ~RBD_SNAP_CREATE_IGNORE_QUIESCE_ERROR;
+  }
+
+  if (api_flags != 0) {
+    lderr(cct) << "invalid snap create flags: "
+                     << std::bitset<32>(api_flags) << dendl;
+    return -EINVAL;
+  }
+
+  return 0;
+}
+
+uint32_t get_default_snap_create_flags(ImageCtx *ictx) {
+  auto mode = ictx->config.get_val<std::string>(
+      "rbd_default_snapshot_quiesce_mode");
+
+  if (mode == "required") {
+    return 0;
+  } else if (mode == "ignore-error") {
+    return RBD_SNAP_CREATE_IGNORE_QUIESCE_ERROR;
+  } else if (mode == "skip") {
+    return RBD_SNAP_CREATE_SKIP_QUIESCE;
+  } else {
+    ceph_abort_msg("invalid rbd_default_snapshot_quiesce_mode");
+  }
+}
+
+SnapContext get_snap_context(
+    const std::optional<
+      std::pair<std::uint64_t,
+                std::vector<std::uint64_t>>>& write_snap_context) {
+  SnapContext snapc;
+  if (write_snap_context) {
+    snapc = SnapContext{write_snap_context->first,
+                        {write_snap_context->second.begin(),
+                         write_snap_context->second.end()}};
+  }
+  return snapc;
+}
+
+uint64_t reserve_async_request_id() {
+  static std::atomic<uint64_t> async_request_seq = 0;
+
+  return ++async_request_seq;
+}
+
+bool is_config_key_uri(const std::string& uri) {
+  return boost::starts_with(uri, CONFIG_KEY_URI_PREFIX);
+}
+
+int get_config_key(librados::Rados& rados, const std::string& uri,
+                   std::string* value) {
+  auto cct = reinterpret_cast<CephContext*>(rados.cct());
+
+  if (!is_config_key_uri(uri)) {
+    return -EINVAL;
+  }
+
+  std::string key = uri.substr(CONFIG_KEY_URI_PREFIX.size());
+  std::string cmd =
+    "{"
+      "\"prefix\": \"config-key get\", "
+      "\"key\": \"" + key + "\""
+    "}";
+
+  bufferlist in_bl;
+  bufferlist out_bl;
+  int r = rados.mon_command(cmd, in_bl, &out_bl, nullptr);
+  if (r < 0) {
+    lderr(cct) << "failed to retrieve MON config key " << key << ": "
+               << cpp_strerror(r) << dendl;
+    return r;
+  }
+
+  *value = std::string(out_bl.c_str(), out_bl.length());
+  return 0;
+}
+
 } // namespace util
 } // namespace librbd