summaryrefslogtreecommitdiffstats
path: root/src/rgw/rgw_sal.cc
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/rgw/rgw_sal.cc402
1 files changed, 402 insertions, 0 deletions
diff --git a/src/rgw/rgw_sal.cc b/src/rgw/rgw_sal.cc
new file mode 100644
index 000000000..58a21f707
--- /dev/null
+++ b/src/rgw/rgw_sal.cc
@@ -0,0 +1,402 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab ft=cpp
+
+/*
+ * Ceph - scalable distributed file system
+ *
+ * Copyright (C) 2019 Red Hat, Inc.
+ *
+ * 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 <errno.h>
+#include <stdlib.h>
+#include <system_error>
+#include <unistd.h>
+#include <sstream>
+
+#include "common/errno.h"
+
+#include "rgw_sal.h"
+#include "rgw_sal_rados.h"
+#include "driver/rados/config/store.h"
+#include "driver/json_config/store.h"
+#include "rgw_d3n_datacache.h"
+
+#ifdef WITH_RADOSGW_DBSTORE
+#include "rgw_sal_dbstore.h"
+#include "driver/dbstore/config/store.h"
+#endif
+
+#ifdef WITH_RADOSGW_MOTR
+#include "rgw_sal_motr.h"
+#endif
+
+#ifdef WITH_RADOSGW_DAOS
+#include "rgw_sal_daos.h"
+#endif
+
+#define dout_subsys ceph_subsys_rgw
+
+extern "C" {
+extern rgw::sal::Driver* newRadosStore(void);
+#ifdef WITH_RADOSGW_DBSTORE
+extern rgw::sal::Driver* newDBStore(CephContext *cct);
+#endif
+#ifdef WITH_RADOSGW_MOTR
+extern rgw::sal::Driver* newMotrStore(CephContext *cct);
+#endif
+#ifdef WITH_RADOSGW_DAOS
+extern rgw::sal::Driver* newDaosStore(CephContext *cct);
+#endif
+extern rgw::sal::Driver* newBaseFilter(rgw::sal::Driver* next);
+
+}
+
+RGWObjState::RGWObjState() {
+}
+
+RGWObjState::~RGWObjState() {
+}
+
+RGWObjState::RGWObjState(const RGWObjState& rhs) : obj (rhs.obj) {
+ is_atomic = rhs.is_atomic;
+ has_attrs = rhs.has_attrs;
+ exists = rhs.exists;
+ size = rhs.size;
+ accounted_size = rhs.accounted_size;
+ mtime = rhs.mtime;
+ epoch = rhs.epoch;
+ if (rhs.obj_tag.length()) {
+ obj_tag = rhs.obj_tag;
+ }
+ if (rhs.tail_tag.length()) {
+ tail_tag = rhs.tail_tag;
+ }
+ write_tag = rhs.write_tag;
+ fake_tag = rhs.fake_tag;
+ shadow_obj = rhs.shadow_obj;
+ has_data = rhs.has_data;
+ if (rhs.data.length()) {
+ data = rhs.data;
+ }
+ prefetch_data = rhs.prefetch_data;
+ keep_tail = rhs.keep_tail;
+ is_olh = rhs.is_olh;
+ objv_tracker = rhs.objv_tracker;
+ pg_ver = rhs.pg_ver;
+ compressed = rhs.compressed;
+}
+
+rgw::sal::Driver* DriverManager::init_storage_provider(const DoutPrefixProvider* dpp,
+ CephContext* cct,
+ const Config& cfg,
+ bool use_gc_thread,
+ bool use_lc_thread,
+ bool quota_threads,
+ bool run_sync_thread,
+ bool run_reshard_thread,
+ bool use_cache,
+ bool use_gc)
+{
+ rgw::sal::Driver* driver{nullptr};
+
+ if (cfg.store_name.compare("rados") == 0) {
+ driver = newRadosStore();
+ RGWRados* rados = static_cast<rgw::sal::RadosStore* >(driver)->getRados();
+
+ if ((*rados).set_use_cache(use_cache)
+ .set_use_datacache(false)
+ .set_use_gc(use_gc)
+ .set_run_gc_thread(use_gc_thread)
+ .set_run_lc_thread(use_lc_thread)
+ .set_run_quota_threads(quota_threads)
+ .set_run_sync_thread(run_sync_thread)
+ .set_run_reshard_thread(run_reshard_thread)
+ .init_begin(cct, dpp) < 0) {
+ delete driver;
+ return nullptr;
+ }
+ if (driver->initialize(cct, dpp) < 0) {
+ delete driver;
+ return nullptr;
+ }
+ if (rados->init_complete(dpp) < 0) {
+ delete driver;
+ return nullptr;
+ }
+ }
+ else if (cfg.store_name.compare("d3n") == 0) {
+ driver = new rgw::sal::RadosStore();
+ RGWRados* rados = new D3nRGWDataCache<RGWRados>;
+ dynamic_cast<rgw::sal::RadosStore*>(driver)->setRados(rados);
+ rados->set_store(static_cast<rgw::sal::RadosStore* >(driver));
+
+ if ((*rados).set_use_cache(use_cache)
+ .set_use_datacache(true)
+ .set_run_gc_thread(use_gc_thread)
+ .set_run_lc_thread(use_lc_thread)
+ .set_run_quota_threads(quota_threads)
+ .set_run_sync_thread(run_sync_thread)
+ .set_run_reshard_thread(run_reshard_thread)
+ .init_begin(cct, dpp) < 0) {
+ delete driver;
+ return nullptr;
+ }
+ if (driver->initialize(cct, dpp) < 0) {
+ delete driver;
+ return nullptr;
+ }
+ if (rados->init_complete(dpp) < 0) {
+ delete driver;
+ return nullptr;
+ }
+
+ lsubdout(cct, rgw, 1) << "rgw_d3n: rgw_d3n_l1_local_datacache_enabled=" <<
+ cct->_conf->rgw_d3n_l1_local_datacache_enabled << dendl;
+ lsubdout(cct, rgw, 1) << "rgw_d3n: rgw_d3n_l1_datacache_persistent_path='" <<
+ cct->_conf->rgw_d3n_l1_datacache_persistent_path << "'" << dendl;
+ lsubdout(cct, rgw, 1) << "rgw_d3n: rgw_d3n_l1_datacache_size=" <<
+ cct->_conf->rgw_d3n_l1_datacache_size << dendl;
+ lsubdout(cct, rgw, 1) << "rgw_d3n: rgw_d3n_l1_evict_cache_on_start=" <<
+ cct->_conf->rgw_d3n_l1_evict_cache_on_start << dendl;
+ lsubdout(cct, rgw, 1) << "rgw_d3n: rgw_d3n_l1_fadvise=" <<
+ cct->_conf->rgw_d3n_l1_fadvise << dendl;
+ lsubdout(cct, rgw, 1) << "rgw_d3n: rgw_d3n_l1_eviction_policy=" <<
+ cct->_conf->rgw_d3n_l1_eviction_policy << dendl;
+ }
+#ifdef WITH_RADOSGW_DBSTORE
+ else if (cfg.store_name.compare("dbstore") == 0) {
+ driver = newDBStore(cct);
+
+ if ((*(rgw::sal::DBStore*)driver).set_run_lc_thread(use_lc_thread)
+ .initialize(cct, dpp) < 0) {
+ delete driver;
+ return nullptr;
+ }
+ }
+#endif
+
+#ifdef WITH_RADOSGW_MOTR
+ else if (cfg.store_name.compare("motr") == 0) {
+ driver = newMotrStore(cct);
+ if (driver == nullptr) {
+ ldpp_dout(dpp, 0) << "newMotrStore() failed!" << dendl;
+ return driver;
+ }
+ ((rgw::sal::MotrStore *)driver)->init_metadata_cache(dpp, cct);
+
+ return store;
+ }
+#endif
+
+#ifdef WITH_RADOSGW_DAOS
+ else if (cfg.store_name.compare("daos") == 0) {
+ driver = newDaosStore(cct);
+ if (driver == nullptr) {
+ ldpp_dout(dpp, 0) << "newDaosStore() failed!" << dendl;
+ return driver;
+ }
+ int ret = driver->initialize(cct, dpp);
+ if (ret != 0) {
+ ldpp_dout(dpp, 20) << "ERROR: store->initialize() failed: " << ret << dendl;
+ delete driver;
+ return nullptr;
+ }
+ }
+#endif
+
+ if (cfg.filter_name.compare("base") == 0) {
+ rgw::sal::Driver* next = driver;
+ driver = newBaseFilter(next);
+
+ if (driver->initialize(cct, dpp) < 0) {
+ delete driver;
+ delete next;
+ return nullptr;
+ }
+ }
+
+ return driver;
+}
+
+rgw::sal::Driver* DriverManager::init_raw_storage_provider(const DoutPrefixProvider* dpp, CephContext* cct, const Config& cfg)
+{
+ rgw::sal::Driver* driver = nullptr;
+ if (cfg.store_name.compare("rados") == 0) {
+ driver = newRadosStore();
+ RGWRados* rados = static_cast<rgw::sal::RadosStore* >(driver)->getRados();
+
+ rados->set_context(cct);
+
+ int ret = rados->init_svc(true, dpp);
+ if (ret < 0) {
+ ldout(cct, 0) << "ERROR: failed to init services (ret=" << cpp_strerror(-ret) << ")" << dendl;
+ delete driver;
+ return nullptr;
+ }
+
+ if (rados->init_rados() < 0) {
+ delete driver;
+ return nullptr;
+ }
+ if (driver->initialize(cct, dpp) < 0) {
+ delete driver;
+ return nullptr;
+ }
+ } else if (cfg.store_name.compare("dbstore") == 0) {
+#ifdef WITH_RADOSGW_DBSTORE
+ driver = newDBStore(cct);
+
+ if ((*(rgw::sal::DBStore*)driver).initialize(cct, dpp) < 0) {
+ delete driver;
+ return nullptr;
+ }
+#else
+ driver = nullptr;
+#endif
+ } else if (cfg.store_name.compare("motr") == 0) {
+#ifdef WITH_RADOSGW_MOTR
+ driver = newMotrStore(cct);
+#else
+ driver = nullptr;
+#endif
+ } else if (cfg.store_name.compare("daos") == 0) {
+#ifdef WITH_RADOSGW_DAOS
+ driver = newDaosStore(cct);
+
+ if (driver->initialize(cct, dpp) < 0) {
+ delete driver;
+ return nullptr;
+ }
+#else
+ driver = nullptr;
+#endif
+ }
+
+ if (cfg.filter_name.compare("base") == 0) {
+ rgw::sal::Driver* next = driver;
+ driver = newBaseFilter(next);
+
+ if (driver->initialize(cct, dpp) < 0) {
+ delete driver;
+ delete next;
+ return nullptr;
+ }
+ }
+
+ return driver;
+}
+
+void DriverManager::close_storage(rgw::sal::Driver* driver)
+{
+ if (!driver)
+ return;
+
+ driver->finalize();
+
+ delete driver;
+}
+
+DriverManager::Config DriverManager::get_config(bool admin, CephContext* cct)
+{
+ DriverManager::Config cfg;
+
+ // Get the store backend
+ const auto& config_store = g_conf().get_val<std::string>("rgw_backend_store");
+ if (config_store == "rados") {
+ cfg.store_name = "rados";
+
+ /* Check to see if d3n is configured, but only for non-admin */
+ const auto& d3n = g_conf().get_val<bool>("rgw_d3n_l1_local_datacache_enabled");
+ if (!admin && d3n) {
+ if (g_conf().get_val<Option::size_t>("rgw_max_chunk_size") !=
+ g_conf().get_val<Option::size_t>("rgw_obj_stripe_size")) {
+ lsubdout(cct, rgw_datacache, 0) << "rgw_d3n: WARNING: D3N DataCache disabling (D3N requires that the chunk_size equals stripe_size)" << dendl;
+ } else if (!g_conf().get_val<bool>("rgw_beast_enable_async")) {
+ lsubdout(cct, rgw_datacache, 0) << "rgw_d3n: WARNING: D3N DataCache disabling (D3N requires yield context - rgw_beast_enable_async=true)" << dendl;
+ } else {
+ cfg.store_name = "d3n";
+ }
+ }
+ }
+#ifdef WITH_RADOSGW_DBSTORE
+ else if (config_store == "dbstore") {
+ cfg.store_name = "dbstore";
+ }
+#endif
+#ifdef WITH_RADOSGW_MOTR
+ else if (config_store == "motr") {
+ cfg.store_name = "motr";
+ }
+#endif
+#ifdef WITH_RADOSGW_DAOS
+ else if (config_store == "daos") {
+ cfg.store_name = "daos";
+ }
+#endif
+
+ // Get the filter
+ cfg.filter_name = "none";
+ const auto& config_filter = g_conf().get_val<std::string>("rgw_filter");
+ if (config_filter == "base") {
+ cfg.filter_name = "base";
+ }
+
+ return cfg;
+}
+
+auto DriverManager::create_config_store(const DoutPrefixProvider* dpp,
+ std::string_view type)
+ -> std::unique_ptr<rgw::sal::ConfigStore>
+{
+ try {
+ if (type == "rados") {
+ return rgw::rados::create_config_store(dpp);
+#ifdef WITH_RADOSGW_DBSTORE
+ } else if (type == "dbstore") {
+ const auto uri = g_conf().get_val<std::string>("dbstore_config_uri");
+ return rgw::dbstore::create_config_store(dpp, uri);
+#endif
+ } else if (type == "json") {
+ auto filename = g_conf().get_val<std::string>("rgw_json_config");
+ return rgw::sal::create_json_config_store(dpp, filename);
+ } else {
+ ldpp_dout(dpp, -1) << "ERROR: unrecognized config store type '"
+ << type << "'" << dendl;
+ return nullptr;
+ }
+ } catch (const std::exception& e) {
+ ldpp_dout(dpp, -1) << "ERROR: failed to initialize config store '"
+ << type << "': " << e.what() << dendl;
+ }
+ return nullptr;
+}
+
+namespace rgw::sal {
+int Object::range_to_ofs(uint64_t obj_size, int64_t &ofs, int64_t &end)
+{
+ if (ofs < 0) {
+ ofs += obj_size;
+ if (ofs < 0)
+ ofs = 0;
+ end = obj_size - 1;
+ } else if (end < 0) {
+ end = obj_size - 1;
+ }
+
+ if (obj_size > 0) {
+ if (ofs >= (off_t)obj_size) {
+ return -ERANGE;
+ }
+ if (end >= (off_t)obj_size) {
+ end = obj_size - 1;
+ }
+ }
+ return 0;
+}
+} // namespace rgw::sal