From ca238ba4990766d779b1ca13a1ee87bae4be0fb2 Mon Sep 17 00:00:00 2001 From: Samarah Uriarte Date: Tue, 11 Mar 2025 13:48:21 -0500 Subject: [PATCH] filter/posix: Implement `POSIXUser` as store Signed-off-by: Samarah Uriarte --- src/rgw/CMakeLists.txt | 1 + src/rgw/driver/posix/posixDB.cc | 62 ++++++++++++ src/rgw/driver/posix/posixDB.h | 138 ++++++++++++++++++++++++++ src/rgw/driver/posix/rgw_sal_posix.cc | 96 ++++++++++++------ src/rgw/driver/posix/rgw_sal_posix.h | 31 ++++-- 5 files changed, 292 insertions(+), 36 deletions(-) create mode 100644 src/rgw/driver/posix/posixDB.cc create mode 100644 src/rgw/driver/posix/posixDB.h diff --git a/src/rgw/CMakeLists.txt b/src/rgw/CMakeLists.txt index 18f1213f894..2f4bd0665cb 100644 --- a/src/rgw/CMakeLists.txt +++ b/src/rgw/CMakeLists.txt @@ -259,6 +259,7 @@ if(WITH_RADOSGW_POSIX) list(APPEND librgw_common_srcs driver/posix/rgw_sal_posix.cc driver/posix/lmdb-safe.cc + driver/posix/posixDB.cc driver/posix/notify.cpp) endif() if(WITH_JAEGER) diff --git a/src/rgw/driver/posix/posixDB.cc b/src/rgw/driver/posix/posixDB.cc new file mode 100644 index 00000000000..82a8a7691ef --- /dev/null +++ b/src/rgw/driver/posix/posixDB.cc @@ -0,0 +1,62 @@ +// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- +// vim: ts=8 sw=2 smarttab + +#include "posixDB.h" +#include "log/Log.h" + +using namespace std; + +namespace rgw { namespace store { + +int POSIXUserDB::Initialize(string logfile, int loglevel) +{ + int ret = -1; + const DoutPrefixProvider *dpp = get_def_dpp(); + + if (!cct) { + cout << "Failed to Initialize. No ceph Context \n"; + return -1; + } + + if (loglevel > 0) { + cct->_conf->subsys.set_log_level(ceph_subsys_rgw, loglevel); + } + if (!logfile.empty()) { + cct->_log->set_log_file(logfile); + cct->_log->reopen_log_file(); + } + + db = openDB(dpp); + + if (!db) { + ldpp_dout(dpp, 0) <<"Failed to open database " << dendl; + return ret; + } + + ret = InitializeDBOps(dpp); + + if (ret) { + ldpp_dout(dpp, 0) <<"InitializePOSIXUserDBOps failed " << dendl; + closeDB(dpp); + db = NULL; + return ret; + } + + ldpp_dout(dpp, 0) << "POSIXUserDB successfully initialized - name:" \ + << db_name << "" << dendl; + + return ret; +} + +int POSIXUserDB::Destroy(const DoutPrefixProvider *dpp) +{ + DB::Destroy(dpp); + + ldpp_dout(dpp, 20)<<"POSIXUserDB successfully destroyed - name:" \ + < +#include +#include +#include +#include +#include +#include +#include "fmt/format.h" +#include +#include "rgw_sal_store.h" +#include "rgw_common.h" +#include "driver/dbstore/sqlite/sqliteDB.h" +#include "driver/dbstore/common/dbstore.h" +#include "global/global_context.h" +#include "global/global_init.h" +#include "common/ceph_context.h" +#include "rgw_multi.h" + +#include "driver/rados/rgw_obj_manifest.h" // FIXME: subclass dependency + +namespace rgw { namespace store { + +class POSIXUserDB; + +struct POSIXUserDBOpUserInfo : DBOpUserInfo {}; + +struct POSIXUserDBOpInfo : DBOpInfo {}; + +struct POSIXUserDBOpUserPrepareInfo : DBOpUserPrepareInfo {}; + +struct POSIXUserDBOpPrepareInfo : DBOpPrepareInfo {}; + +struct POSIXUserDBOpPrepareParams : DBOpPrepareParams {}; + +struct POSIXUserDBOps : DBOps {}; + +class POSIXUserDBOp : public DBOp { + private: + static constexpr std::string_view CreateUserTableQ = + /* Corresponds to rgw::sal::User + * + * For now only UserID is made Primary key. + * If multiple tenants are stored in single .db handle, should + * make both (UserID, Tenant) as Primary Key. + * + * XXX: + * - AccessKeys, SwiftKeys, Subusers (map<>) are stored as blob. + * To enable easy query, first accesskey is stored in separate fields + * AccessKeysID, AccessKeysSecret. + * In future, may be have separate table to store these keys and + * query on that table. + * - Quota stored as blob .. should be linked to quota table. + */ + "CREATE TABLE IF NOT EXISTS '{}' ( \ + UserID TEXT NOT NULL UNIQUE, \ + Tenant TEXT , \ + NS TEXT , \ + DisplayName TEXT , \ + UserEmail TEXT , \ + AccessKeysID TEXT , \ + AccessKeysSecret TEXT , \ + AccessKeys BLOB , \ + SwiftKeys BLOB , \ + SubUsers BLOB , \ + Suspended INTEGER , \ + MaxBuckets INTEGER , \ + OpMask INTEGER , \ + UserCaps BLOB , \ + Admin INTEGER , \ + System INTEGER , \ + PlacementName TEXT , \ + PlacementStorageClass TEXT , \ + PlacementTags BLOB , \ + BucketQuota BLOB , \ + TempURLKeys BLOB , \ + UserQuota BLOB , \ + TYPE INTEGER , \ + MfaIDs BLOB , \ + AssumedRoleARN TEXT , \ + UserAttrs BLOB, \ + UserVersion INTEGER, \ + UserVersionTag TEXT, \ + PRIMARY KEY (UserID) \n);"; + + public: + POSIXUserDBOp() : DBOp() {} + virtual ~POSIXUserDBOp() {} + std::mutex mtx; // to protect prepared stmt +}; + +class InsertPOSIXUserOp : public SQLInsertUser {}; + +class RemovePOSIXUserOp: public SQLRemoveUser {}; + +class POSIXUserDB : public SQLiteDB { + private: + const std::string db_name; + rgw::sal::Driver* driver; + const std::string user_table; + + protected: + void *db; + CephContext *cct; + const DoutPrefix dp; + // Below mutex is to protect objectmap and other shared + // objects if any. + std::mutex mtx; + + public: + POSIXUserDB(std::string db_name, CephContext *_cct) : SQLiteDB(db_name, _cct), + db_name(db_name), + user_table(db_name+"_user_table"), + cct(_cct), + dp(_cct, ceph_subsys_rgw, "rgw POSIXUserDBStore backend: ") + {} + /* POSIXUserDB() {}*/ + + int Initialize(std::string logfile, int loglevel); + int Destroy(const DoutPrefixProvider *dpp); + + virtual int InitPrepareParams(const DoutPrefixProvider *dpp, + DBOpPrepareParams &p_params, + DBOpParams* params) { return 0; } // TODO + virtual int createLCTables(const DoutPrefixProvider *dpp) { return 0; } + + virtual int ListAllBuckets(const DoutPrefixProvider *dpp, DBOpParams *params) { return 0; } // TODO + virtual int ListAllUsers(const DoutPrefixProvider *dpp, DBOpParams *params) { return 0; } // TODO + virtual int ListAllObjects(const DoutPrefixProvider *dpp, DBOpParams *params) { return 0; } // TODO +}; + +} } // namespace rgw::store diff --git a/src/rgw/driver/posix/rgw_sal_posix.cc b/src/rgw/driver/posix/rgw_sal_posix.cc index d72b38ee45b..e128a1de5f1 100644 --- a/src/rgw/driver/posix/rgw_sal_posix.cc +++ b/src/rgw/driver/posix/rgw_sal_posix.cc @@ -22,6 +22,8 @@ #include "include/scope_guard.h" #include "common/Clock.h" // for ceph_clock_now() #include "common/errno.h" +#include "driver/dbstore/common/dbstore.h" +#include "rgw_sal_dbstore.h" #define dout_subsys ceph_subsys_rgw #define dout_context g_ceph_context @@ -1867,6 +1869,20 @@ int POSIXDriver::initialize(CephContext *cct, const DoutPrefixProvider *dpp) { FilterDriver::initialize(cct, dpp); + int ret = -1; + const static std::string tenant = "default_ns"; + const auto& db_path = g_conf().get_val("dbstore_db_dir"); + const auto& db_name = g_conf().get_val("dbstore_db_name_prefix") + "-" + tenant; + auto db_full_path = std::filesystem::path(db_path) / db_name; + + userDB = new POSIXUserDB(db_full_path.string(), cct); + + if ((ret = userDB->Initialize("", -1)) < 0) { + ldout(cct, 0) << "User DB initialization failed for tenant("<("rgw_posix_base_path"); ldpp_dout(dpp, 20) << "Initializing POSIX driver: " << base_path << dendl; @@ -1882,7 +1898,7 @@ int POSIXDriver::initialize(CephContext *cct, const DoutPrefixProvider *dpp) g_conf().get_val("rgw_posix_cache_lmdb_count"))); root_dir = std::make_unique(base_path, nullptr, ctx()); - int ret = root_dir->open(dpp); + ret = root_dir->open(dpp); if (ret < 0) { if (ret == -ENOTDIR) { ldpp_dout(dpp, 0) << " ERROR: base path (" << base_path @@ -1905,51 +1921,60 @@ int POSIXDriver::initialize(CephContext *cct, const DoutPrefixProvider *dpp) std::unique_ptr POSIXDriver::get_user(const rgw_user &u) { - std::unique_ptr user = next->get_user(u); - - return std::make_unique(std::move(user), this); + return std::make_unique(this, u); } int POSIXDriver::get_user_by_access_key(const DoutPrefixProvider* dpp, const std::string& key, optional_yield y, std::unique_ptr* user) { - std::unique_ptr nu; - int ret; + RGWUserInfo uinfo; + rgw::sal::Attrs attrs; + RGWObjVersionTracker objv_tracker; + + int ret = userDB->get_user(dpp, std::string("access_key"), key, uinfo, &attrs, + &objv_tracker); - ret = next->get_user_by_access_key(dpp, key, y, &nu); - if (ret != 0) + if (ret < 0) return ret; - User* u = new POSIXUser(std::move(nu), this); + User* u = new POSIXUser(this, uinfo); + + if (!u) + return -ENOMEM; + + u->get_attrs() = std::move(attrs); + u->get_version_tracker() = objv_tracker; user->reset(u); return 0; } int POSIXDriver::get_user_by_email(const DoutPrefixProvider* dpp, const std::string& email, optional_yield y, std::unique_ptr* user) { - std::unique_ptr nu; - int ret; - ret = next->get_user_by_email(dpp, email, y, &nu); - if (ret != 0) + RGWUserInfo uinfo; + rgw::sal::Attrs attrs; + RGWObjVersionTracker objv_tracker; + + int ret = userDB->get_user(dpp, std::string("email"), email, uinfo, &attrs, + &objv_tracker); + + if (ret < 0) return ret; - User* u = new POSIXUser(std::move(nu), this); + User* u = new POSIXUser(this, uinfo); + + if (!u) + return -ENOMEM; + + u->get_attrs() = std::move(attrs); + u->get_version_tracker() = objv_tracker; user->reset(u); return 0; } int POSIXDriver::get_user_by_swift(const DoutPrefixProvider* dpp, const std::string& user_str, optional_yield y, std::unique_ptr* user) { - std::unique_ptr nu; - int ret; - - ret = next->get_user_by_swift(dpp, user_str, y, &nu); - if (ret != 0) - return ret; - - User* u = new POSIXUser(std::move(nu), this); - user->reset(u); - return 0; + /* Swift keys and subusers are not supported by DBStore for now */ + return -ENOTSUP; } std::unique_ptr POSIXDriver::get_object(const rgw_obj_key& k) @@ -2172,28 +2197,41 @@ int POSIXBucket::create(const DoutPrefixProvider* dpp, int POSIXUser::read_attrs(const DoutPrefixProvider* dpp, optional_yield y) { - return next->read_attrs(dpp, y); + return driver->get_user_db()->get_user(dpp, std::string("user_id"), this->get_id().id, this->get_info(), &(this->get_attrs()), + &(this->get_version_tracker())); } int POSIXUser::merge_and_store_attrs(const DoutPrefixProvider* dpp, Attrs& new_attrs, optional_yield y) { - return next->merge_and_store_attrs(dpp, new_attrs, y); + auto attrs = this->get_attrs(); + for(auto& it : new_attrs) { + attrs[it.first] = it.second; + } + + return store_user(dpp, y, false); } int POSIXUser::load_user(const DoutPrefixProvider* dpp, optional_yield y) { - return next->load_user(dpp, y); + return driver->get_user_db()->get_user(dpp, std::string("user_id"), this->get_id().id, this->get_info(), &(this->get_attrs()), + &(this->get_version_tracker())); } int POSIXUser::store_user(const DoutPrefixProvider* dpp, optional_yield y, bool exclusive, RGWUserInfo* old_info) { - return next->store_user(dpp, y, exclusive, old_info); + return driver->get_user_db()->store_user(dpp, this->get_info(), exclusive, &(this->get_attrs()), &(this->get_version_tracker()), old_info); } int POSIXUser::remove_user(const DoutPrefixProvider* dpp, optional_yield y) { - return next->remove_user(dpp, y); + return driver->get_user_db()->remove_user(dpp, this->get_info(), &(this->get_version_tracker())); +} + +int POSIXUser::verify_mfa(const std::string& mfa_str, bool* verified, const DoutPrefixProvider *dpp, optional_yield y) +{ + *verified = false; + return 0; } std::unique_ptr POSIXBucket::get_object(const rgw_obj_key& k) diff --git a/src/rgw/driver/posix/rgw_sal_posix.h b/src/rgw/driver/posix/rgw_sal_posix.h index fdf2b9d510f..3a75cba1315 100644 --- a/src/rgw/driver/posix/rgw_sal_posix.h +++ b/src/rgw/driver/posix/rgw_sal_posix.h @@ -20,6 +20,7 @@ #include #include "common/dout.h" #include "bucket_cache.h" +#include "posixDB.h" namespace rgw { namespace sal { @@ -350,7 +351,7 @@ std::string get_key_fname(rgw_obj_key& key, bool use_version); class POSIXDriver : public FilterDriver { protected: - + rgw::store::POSIXUserDB* userDB; std::unique_ptr bucket_cache; std::string base_path; std::unique_ptr root_dir; @@ -421,6 +422,7 @@ public: /* Internal APIs */ int get_root_fd() { return root_dir->get_fd(); } + rgw::store::POSIXUserDB* get_user_db() { return userDB; } Directory* get_root_dir() { return root_dir.get(); } const std::string& get_base_path() const { return base_path; } BucketCache* get_bucket_cache() { return bucket_cache.get(); } @@ -432,25 +434,40 @@ public: }; -class POSIXUser : public FilterUser { +class POSIXUser : public StoreUser { private: POSIXDriver* driver; public: - POSIXUser(std::unique_ptr _next, POSIXDriver* _driver) : - FilterUser(std::move(_next)), - driver(_driver) {} + POSIXUser(POSIXDriver* _driver) : + StoreUser(), driver(_driver) {} + POSIXUser(POSIXDriver* _driver, const rgw_user& _u) : + StoreUser(_u), driver(_driver) {} + POSIXUser(POSIXDriver* _driver, const RGWUserInfo& _info) : + StoreUser(_info), driver(_driver) {} virtual ~POSIXUser() = default; - virtual Attrs& get_attrs() override { return next->get_attrs(); } - virtual void set_attrs(Attrs& _attrs) override { next->set_attrs(_attrs); } + virtual std::unique_ptr clone() override { + return std::unique_ptr(new POSIXUser(*this)); + } virtual int read_attrs(const DoutPrefixProvider* dpp, optional_yield y) override; virtual int merge_and_store_attrs(const DoutPrefixProvider* dpp, Attrs& new_attrs, optional_yield y) override; + virtual int read_usage(const DoutPrefixProvider *dpp, uint64_t start_epoch, + uint64_t end_epoch, uint32_t max_entries, + bool* is_truncated, RGWUsageIter& usage_iter, + std::map& usage) override { return 0; } + virtual int trim_usage(const DoutPrefixProvider *dpp, uint64_t start_epoch, + uint64_t end_epoch, optional_yield y) override { return 0; } virtual int load_user(const DoutPrefixProvider* dpp, optional_yield y) override; virtual int store_user(const DoutPrefixProvider* dpp, optional_yield y, bool exclusive, RGWUserInfo* old_info = nullptr) override; virtual int remove_user(const DoutPrefixProvider* dpp, optional_yield y) override; + virtual int verify_mfa(const std::string& mfa_str, bool* verified, + const DoutPrefixProvider* dpp, optional_yield y) override; + int list_groups(const DoutPrefixProvider* dpp, optional_yield y, + std::string_view marker, uint32_t max_items, + GroupList& listing) override { return -ENOTSUP; } }; class POSIXBucket : public StoreBucket { -- 2.39.5