Add placeholder APIs to create and store LC related state.
Signed-off-by: Soumya Koduri <skoduri@redhat.com>
#ifdef WITH_RADOSGW_DBSTORE
rgw::sal::Store* store = newDBStore(cct);
- /* Initialize the dbstore with cct & dpp */
- DB *db = static_cast<rgw::sal::DBStore *>(store)->getDB();
- db->set_context(cct);
+ if ((*(rgw::sal::DBStore*)store).set_run_lc_thread(use_lc_thread)
+ .initialize(cct, dpp) < 0) {
+ delete store; store = nullptr;
+ }
/* XXX: temporary - create testid user */
rgw_user testid_user("", "testid", "");
std::unique_ptr<Lifecycle> DBStore::get_lifecycle(void)
{
- return 0;
+ return std::make_unique<DBLifecycle>(this);
}
std::unique_ptr<Completions> DBStore::get_completions(void)
return 0;
}
+ int DBLifecycle::get_entry(const std::string& oid, const std::string& marker,
+ LCEntry& entry)
+ {
+ return 0;
+ }
+
+ int DBLifecycle::get_next_entry(const std::string& oid, std::string& marker,
+ LCEntry& entry)
+ {
+ return 0;
+ }
+
+ int DBLifecycle::set_entry(const std::string& oid, const LCEntry& entry)
+ {
+ return 0;
+ }
+
+ int DBLifecycle::list_entries(const std::string& oid, const std::string& marker,
+ uint32_t max_entries, vector<LCEntry>& entries)
+ {
+ return 0;
+ }
+
+ int DBLifecycle::rm_entry(const std::string& oid, const LCEntry& entry)
+ {
+ return 0;
+ }
+
+ int DBLifecycle::get_head(const std::string& oid, LCHead& head)
+ {
+ return 0;
+ }
+
+ int DBLifecycle::put_head(const std::string& oid, const LCHead& head)
+ {
+ return 0;
+ }
+
+ LCSerializer* DBLifecycle::get_serializer(const std::string& lock_name, const std::string& oid, const std::string& cookie)
+ {
+ return new LCDBSerializer(store, oid, lock_name, cookie);
+ }
+
std::unique_ptr<Notification> DBStore::get_notification(rgw::sal::Object* obj,
struct req_state* s,
rgw::notify::EventType event_type, const std::string* object_name)
return std::make_unique<DBNotification>(obj, event_type);
}
+ RGWLC* DBStore::get_rgwlc(void) {
+ return lc;
+ }
+
int DBStore::log_usage(const DoutPrefixProvider *dpp, map<rgw_user_bucket, RGWUsageBatch>& usage_info)
{
return 0;
return 0;
}
+ int DBStore::initialize(CephContext *_cct, const DoutPrefixProvider *_dpp) {
+ int ret = 0;
+ cct = _cct;
+ dpp = _dpp;
+
+ lc = new RGWLC();
+ lc->initialize(cct, this);
+
+ if (use_lc_thread) {
+ ret = db->createLCTables(dpp);
+ lc->start_processor();
+ }
+
+ return ret;
+ }
} // namespace rgw::sal
extern "C" {
store->setDBStoreManager(dbsm);
store->setDB(db);
db->set_store((rgw::sal::Store*)store);
+ db->set_context(cct);
}
return store;
#include "rgw_sal.h"
#include "rgw_oidc_provider.h"
#include "rgw_role.h"
+#include "rgw_lc.h"
#include "store/dbstore/common/dbstore.h"
#include "store/dbstore/dbstore_mgr.h"
class DBStore;
+class LCDBSerializer : public LCSerializer {
+ const std::string oid;
+
+public:
+ LCDBSerializer(DBStore* store, const std::string& oid, const std::string& lock_name, const std::string& cookie) {}
+
+ virtual int try_lock(const DoutPrefixProvider *dpp, utime_t dur, optional_yield y) override { return 0; }
+ virtual int unlock() override {
+ return 0;
+ }
+};
+
+class DBLifecycle : public Lifecycle {
+ DBStore* store;
+
+public:
+ DBLifecycle(DBStore* _st) : store(_st) {}
+
+ virtual int get_entry(const std::string& oid, const std::string& marker, LCEntry& entry) override;
+ virtual int get_next_entry(const std::string& oid, std::string& marker, LCEntry& entry) override;
+ virtual int set_entry(const std::string& oid, const LCEntry& entry) override;
+ virtual int list_entries(const std::string& oid, const std::string& marker,
+ uint32_t max_entries, std::vector<LCEntry>& entries) override;
+ virtual int rm_entry(const std::string& oid, const LCEntry& entry) override;
+ virtual int get_head(const std::string& oid, LCHead& head) override;
+ virtual int put_head(const std::string& oid, const LCHead& head) override;
+ virtual LCSerializer* get_serializer(const std::string& lock_name, const std::string& oid, const std::string& cookie) override;
+};
+
class DBNotification : public Notification {
protected:
Object* obj;
string luarocks_path;
DBZone zone;
RGWSyncModuleInstanceRef sync_module;
+ RGWLC* lc;
+ CephContext *cct;
+ const DoutPrefixProvider *dpp;
+ bool use_lc_thread;
public:
- DBStore(): dbsm(nullptr), zone(this) {}
+ DBStore(): dbsm(nullptr), zone(this), cct(nullptr), dpp(nullptr),
+ use_lc_thread(false) {}
~DBStore() { delete dbsm; }
+ DBStore& set_run_lc_thread(bool _use_lc_thread) {
+ use_lc_thread = _use_lc_thread;
+ return *this;
+ }
+
+ int initialize(CephContext *cct, const DoutPrefixProvider *dpp);
virtual std::unique_ptr<User> get_user(const rgw_user& u) override;
virtual int get_user_by_access_key(const DoutPrefixProvider *dpp, const std::string& key, optional_yield y, std::unique_ptr<User>* user) override;
virtual int get_user_by_email(const DoutPrefixProvider *dpp, const std::string& email, optional_yield y, std::unique_ptr<User>* user) override;
virtual std::unique_ptr<Completions> get_completions(void) override;
virtual std::unique_ptr<Notification> get_notification(rgw::sal::Object* obj, struct req_state* s,
rgw::notify::EventType event_type, const std::string* object_name=nullptr) override;
- virtual RGWLC* get_rgwlc(void) override { return NULL; }
+ virtual RGWLC* get_rgwlc(void) override;
virtual RGWCoroutinesManagerRegistry* get_cr_registry() override { return NULL; }
virtual int log_usage(const DoutPrefixProvider *dpp, map<rgw_user_bucket, RGWUsageBatch>& usage_info) override;
/* Below are subject to change */
string objectdata_table;
string quota_table;
+ string lc_head_table;
+ string lc_entry_table;
string obj;
};
/* below subject to change */
string objectdata_table;
string quota_table;
+ string lc_head_table;
+ string lc_entry_table;
};
struct DBOps {
Enabled Boolean , \
CheckOnRaw Boolean \n);";
+ const string CreateLCEntryTableQ =
+ "CREATE TABLE IF NOT EXISTS '{}' ( \
+ LCIndex TEXT NOT NULL, \
+ BucketName TEXT NOT NULL , \
+ StartTime INTEGER , \
+ Status INTEGER, \
+ PRIMARY KEY (LCIndex, BucketName), \
+ FOREIGN KEY (BucketName) \
+ REFERENCES '{}' (BucketName) ON DELETE CASCADE ON UPDATE CASCADE \n);";
+
+ const string CreateLCHeadTableQ =
+ "CREATE TABLE IF NOT EXISTS '{}' ( \
+ LCIndex TEXT NOT NULL, \
+ Marker TEXT, \
+ StartDate INTEGER , \
+ PRIMARY KEY (LCIndex) \n);";
+
+
const string DropQ = "DROP TABLE IF EXISTS '{}'";
const string ListAllQ = "SELECT * from '{}'";
if (!type.compare("Quota"))
return fmt::format(CreateQuotaTableQ.c_str(),
params->quota_table.c_str());
+ if (!type.compare("LCHead"))
+ return fmt::format(CreateLCHeadTableQ.c_str(),
+ params->lc_head_table.c_str());
+ if (!type.compare("LCEntry"))
+ return fmt::format(CreateLCEntryTableQ.c_str(),
+ params->lc_entry_table.c_str(),
+ params->bucket_table.c_str());
ldout(params->cct, 0) << "Incorrect table type("<<type<<") specified" << dendl;
const string user_table;
const string bucket_table;
const string quota_table;
+ const string lc_head_table;
+ const string lc_entry_table;
static map<string, class ObjectOp*> objectmap;
pthread_mutex_t mutex; // to protect objectmap and other shared
// objects if any. This mutex is taken
user_table(db_name+".user.table"),
bucket_table(db_name+".bucket.table"),
quota_table(db_name+".quota.table"),
+ lc_head_table(db_name+".lc_head.table"),
+ lc_entry_table(db_name+".lc_entry.table"),
cct(_cct),
dp(_cct, dout_subsys, "rgw DBStore backend: ")
{}
user_table(db_name+".user.table"),
bucket_table(db_name+".bucket.table"),
quota_table(db_name+".quota.table"),
+ lc_head_table(db_name+".lc_head.table"),
+ lc_entry_table(db_name+".lc_entry.table"),
cct(_cct),
dp(_cct, dout_subsys, "rgw DBStore backend: ")
{}
const string getUserTable() { return user_table; }
const string getBucketTable() { return bucket_table; }
const string getQuotaTable() { return quota_table; }
+ const string getLCHeadTable() { return lc_head_table; }
+ const string getLCEntryTable() { return lc_entry_table; }
const string getObjectTable(string bucket) {
return db_name+"."+bucket+".object.table"; }
const string getObjectDataTable(string bucket) {
virtual int InitializeDBOps(const DoutPrefixProvider *dpp) { return 0; }
virtual int FreeDBOps(const DoutPrefixProvider *dpp) { return 0; }
virtual int InitPrepareParams(const DoutPrefixProvider *dpp, DBOpPrepareParams ¶ms) = 0;
+ virtual int createLCTables(const DoutPrefixProvider *dpp) = 0;
virtual int ListAllBuckets(const DoutPrefixProvider *dpp, DBOpParams *params) = 0;
virtual int ListAllUsers(const DoutPrefixProvider *dpp, DBOpParams *params) = 0;
int SQLiteDB::createTables(const DoutPrefixProvider *dpp)
{
int ret = -1;
- int cu, cb = -1;
+ int cu = 0, cb = 0, cq = 0;
DBOpParams params = {};
params.user_table = getUserTable();
if ((cb = createBucketTable(dpp, ¶ms)))
goto out;
- if ((cb = createQuotaTable(dpp, ¶ms)))
+ if ((cq = createQuotaTable(dpp, ¶ms)))
goto out;
ret = 0;
return ret;
}
+int SQLiteDB::createLCTables(const DoutPrefixProvider *dpp)
+{
+ int ret = -1;
+ string schema;
+ DBOpParams params = {};
+
+ params.lc_entry_table = getLCEntryTable();
+ params.lc_head_table = getLCHeadTable();
+ params.bucket_table = getBucketTable();
+
+ schema = CreateTableSchema("LCEntry", ¶ms);
+ ret = exec(dpp, schema.c_str(), NULL);
+ if (ret) {
+ ldpp_dout(dpp, 0)<<"CreateLCEntryTable failed" << dendl;
+ return ret;
+ }
+ ldpp_dout(dpp, 20)<<"CreateLCEntryTable suceeded" << dendl;
+
+ schema = CreateTableSchema("LCHead", ¶ms);
+ ret = exec(dpp, schema.c_str(), NULL);
+ if (ret) {
+ ldpp_dout(dpp, 0)<<"CreateLCHeadTable failed" << dendl;
+ (void)DeleteLCEntryTable(dpp, ¶ms);
+ }
+ ldpp_dout(dpp, 20)<<"CreateLCHeadTable suceeded" << dendl;
+
+ return ret;
+}
+
int SQLiteDB::DeleteUserTable(const DoutPrefixProvider *dpp, DBOpParams *params)
{
int ret = -1;
return ret;
}
+int SQLiteDB::DeleteQuotaTable(const DoutPrefixProvider *dpp, DBOpParams *params)
+{
+ int ret = -1;
+ string schema;
+
+ schema = DeleteTableSchema(params->quota_table);
+
+ ret = exec(dpp, schema.c_str(), NULL);
+ if (ret)
+ ldpp_dout(dpp, 0)<<"DeleteQuotaTable failed " << dendl;
+
+ ldpp_dout(dpp, 20)<<"DeleteQuotaTable suceeded " << dendl;
+
+ return ret;
+}
+
+int SQLiteDB::DeleteLCEntryTable(const DoutPrefixProvider *dpp, DBOpParams *params)
+{
+ int ret = -1;
+ string schema;
+
+ schema = DeleteTableSchema(params->lc_entry_table);
+ ret = exec(dpp, schema.c_str(), NULL);
+ if (ret)
+ ldpp_dout(dpp, 0)<<"DeleteLCEntryTable failed " << dendl;
+ ldpp_dout(dpp, 20)<<"DeleteLCEntryTable suceeded " << dendl;
+
+ return ret;
+}
+
+int SQLiteDB::DeleteLCHeadTable(const DoutPrefixProvider *dpp, DBOpParams *params)
+{
+ int ret = -1;
+ string schema;
+
+ schema = DeleteTableSchema(params->lc_head_table);
+ ret = exec(dpp, schema.c_str(), NULL);
+ if (ret)
+ ldpp_dout(dpp, 0)<<"DeleteLCHeadTable failed " << dendl;
+ ldpp_dout(dpp, 20)<<"DeleteLCHeadTable suceeded " << dendl;
+
+ return ret;
+}
+
int SQLiteDB::ListAllUsers(const DoutPrefixProvider *dpp, DBOpParams *params)
{
int ret = -1;
int createObjectDataTable(const DoutPrefixProvider *dpp, DBOpParams *params);
int createQuotaTable(const DoutPrefixProvider *dpp, DBOpParams *params);
+ int createLCTables(const DoutPrefixProvider *dpp) override;
+
int DeleteBucketTable(const DoutPrefixProvider *dpp, DBOpParams *params);
int DeleteUserTable(const DoutPrefixProvider *dpp, DBOpParams *params);
int DeleteObjectTable(const DoutPrefixProvider *dpp, DBOpParams *params);
int DeleteObjectDataTable(const DoutPrefixProvider *dpp, DBOpParams *params);
+ int DeleteQuotaTable(const DoutPrefixProvider *dpp, DBOpParams *params);
+ int DeleteLCEntryTable(const DoutPrefixProvider *dpp, DBOpParams *params);
+ int DeleteLCHeadTable(const DoutPrefixProvider *dpp, DBOpParams *params);
int ListAllBuckets(const DoutPrefixProvider *dpp, DBOpParams *params) override;
int ListAllUsers(const DoutPrefixProvider *dpp, DBOpParams *params) override;
ASSERT_EQ(ret, 0);
}
+TEST_F(DBStoreTest, LCTables) {
+ struct DBOpParams params = GlobalParams;
+ int ret = -1;
+
+ ret = db->createLCTables(dpp);
+ ASSERT_EQ(ret, 0);
+}
+
int main(int argc, char **argv)
{
int ret = -1;