diff options
Diffstat (limited to '')
-rw-r--r-- | src/rgw/rgw_sal.cc | 402 |
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 |