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)
--- /dev/null
+// -*- 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:" \
+ <<db_name << dendl;
+
+ return 0;
+}
+
+} } // namespace rgw::store
+
--- /dev/null
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+
+#pragma once
+
+#include "driver/rados/rgw_bucket.h"
+
+#include <errno.h>
+#include <stdlib.h>
+#include <string>
+#include <stdio.h>
+#include <iostream>
+#include <mutex>
+#include <condition_variable>
+#include "fmt/format.h"
+#include <map>
+#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
#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
{
FilterDriver::initialize(cct, dpp);
+ int ret = -1;
+ const static std::string tenant = "default_ns";
+ const auto& db_path = g_conf().get_val<std::string>("dbstore_db_dir");
+ const auto& db_name = g_conf().get_val<std::string>("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("<<tenant<<")" << dendl;
+ delete userDB;
+ return ret;
+ }
+
base_path = g_conf().get_val<std::string>("rgw_posix_base_path");
ldpp_dout(dpp, 20) << "Initializing POSIX driver: " << base_path << dendl;
g_conf().get_val<int64_t>("rgw_posix_cache_lmdb_count")));
root_dir = std::make_unique<Directory>(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
std::unique_ptr<User> POSIXDriver::get_user(const rgw_user &u)
{
- std::unique_ptr<User> user = next->get_user(u);
-
- return std::make_unique<POSIXUser>(std::move(user), this);
+ return std::make_unique<POSIXUser>(this, u);
}
int POSIXDriver::get_user_by_access_key(const DoutPrefixProvider* dpp, const std::string& key, optional_yield y, std::unique_ptr<User>* user)
{
- std::unique_ptr<User> 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>* user)
{
- std::unique_ptr<User> 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>* user)
{
- std::unique_ptr<User> 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<Object> POSIXDriver::get_object(const rgw_obj_key& k)
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<Object> POSIXBucket::get_object(const rgw_obj_key& k)
#include <memory>
#include "common/dout.h"
#include "bucket_cache.h"
+#include "posixDB.h"
namespace rgw { namespace sal {
class POSIXDriver : public FilterDriver {
protected:
-
+ rgw::store::POSIXUserDB* userDB;
std::unique_ptr<BucketCache> bucket_cache;
std::string base_path;
std::unique_ptr<Directory> root_dir;
/* 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(); }
};
-class POSIXUser : public FilterUser {
+class POSIXUser : public StoreUser {
private:
POSIXDriver* driver;
public:
- POSIXUser(std::unique_ptr<User> _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<User> clone() override {
+ return std::unique_ptr<User>(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<rgw_user_bucket, rgw_usage_log_entry>& 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 {