From e6918187568dbd01842d8d1d2c808ce16a894239 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Sun, 21 Apr 2024 13:54:28 +0200 Subject: Adding upstream version 18.2.2. Signed-off-by: Daniel Baumann --- src/rgw/driver/rados/rgw_sal_rados.h | 978 +++++++++++++++++++++++++++++++++++ 1 file changed, 978 insertions(+) create mode 100644 src/rgw/driver/rados/rgw_sal_rados.h (limited to 'src/rgw/driver/rados/rgw_sal_rados.h') diff --git a/src/rgw/driver/rados/rgw_sal_rados.h b/src/rgw/driver/rados/rgw_sal_rados.h new file mode 100644 index 000000000..4d2dc9709 --- /dev/null +++ b/src/rgw/driver/rados/rgw_sal_rados.h @@ -0,0 +1,978 @@ +// -*- 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) 2020 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. + * + */ + +#pragma once + +#include "rgw_sal_store.h" +#include "rgw_rados.h" +#include "rgw_notify.h" +#include "rgw_oidc_provider.h" +#include "rgw_role.h" +#include "rgw_multi.h" +#include "rgw_putobj_processor.h" +#include "services/svc_tier_rados.h" +#include "cls/lock/cls_lock_client.h" + +namespace rgw { namespace sal { + +class RadosMultipartUpload; + +class RadosCompletions : public Completions { + public: + std::list handles; + RadosCompletions() {} + ~RadosCompletions() = default; + virtual int drain() override; +}; + +class RadosPlacementTier: public StorePlacementTier { + RadosStore* store; + RGWZoneGroupPlacementTier tier; +public: + RadosPlacementTier(RadosStore* _store, const RGWZoneGroupPlacementTier& _tier) : store(_store), tier(_tier) {} + virtual ~RadosPlacementTier() = default; + + virtual const std::string& get_tier_type() { return tier.tier_type; } + virtual const std::string& get_storage_class() { return tier.storage_class; } + virtual bool retain_head_object() { return tier.retain_head_object; } + RGWZoneGroupPlacementTier& get_rt() { return tier; } +}; + +class RadosZoneGroup : public StoreZoneGroup { + RadosStore* store; + const RGWZoneGroup group; + std::string empty; +public: + RadosZoneGroup(RadosStore* _store, const RGWZoneGroup& _group) : store(_store), group(_group) {} + virtual ~RadosZoneGroup() = default; + + virtual const std::string& get_id() const override { return group.get_id(); }; + virtual const std::string& get_name() const override { return group.get_name(); }; + virtual int equals(const std::string& other_zonegroup) const override { + return group.equals(other_zonegroup); + }; + /** Get the endpoint from zonegroup, or from master zone if not set */ + virtual const std::string& get_endpoint() const override; + virtual bool placement_target_exists(std::string& target) const override; + virtual bool is_master_zonegroup() const override { + return group.is_master_zonegroup(); + }; + virtual const std::string& get_api_name() const override { return group.api_name; }; + virtual void get_placement_target_names(std::set& names) const override; + virtual const std::string& get_default_placement_name() const override { + return group.default_placement.name; }; + virtual int get_hostnames(std::list& names) const override { + names = group.hostnames; + return 0; + }; + virtual int get_s3website_hostnames(std::list& names) const override { + names = group.hostnames_s3website; + return 0; + }; + virtual int get_zone_count() const override { + return group.zones.size(); + } + virtual int get_placement_tier(const rgw_placement_rule& rule, std::unique_ptr* tier); + virtual int get_zone_by_id(const std::string& id, std::unique_ptr* zone) override; + virtual int get_zone_by_name(const std::string& name, std::unique_ptr* zone) override; + virtual int list_zones(std::list& zone_ids) override; + bool supports(std::string_view feature) const override { + return group.supports(feature); + } + virtual std::unique_ptr clone() override { + return std::make_unique(store, group); + } + const RGWZoneGroup& get_group() const { return group; } +}; + +class RadosZone : public StoreZone { + protected: + RadosStore* store; + std::unique_ptr group; + RGWZone rgw_zone; + bool local_zone{false}; + public: + RadosZone(RadosStore* _store, std::unique_ptr _zg) : store(_store), group(std::move(_zg)), local_zone(true) {} + RadosZone(RadosStore* _store, std::unique_ptr _zg, RGWZone& z) : store(_store), group(std::move(_zg)), rgw_zone(z) {} + ~RadosZone() = default; + + virtual std::unique_ptr clone() override; + virtual ZoneGroup& get_zonegroup() override { return *(group.get()); } + virtual const std::string& get_id() override; + virtual const std::string& get_name() const override; + virtual bool is_writeable() override; + virtual bool get_redirect_endpoint(std::string* endpoint) override; + virtual bool has_zonegroup_api(const std::string& api) const override; + virtual const std::string& get_current_period_id() override; + virtual const RGWAccessKey& get_system_key() override; + virtual const std::string& get_realm_name() override; + virtual const std::string& get_realm_id() override; + virtual const std::string_view get_tier_type() override; + virtual RGWBucketSyncPolicyHandlerRef get_sync_policy_handler() override; +}; + +class RadosStore : public StoreDriver { + private: + RGWRados* rados; + RGWUserCtl* user_ctl; + std::unique_ptr zone; + std::string topics_oid(const std::string& tenant) const; + + public: + RadosStore() + : rados(nullptr) { + } + ~RadosStore() { + delete rados; + } + + virtual int initialize(CephContext *cct, const DoutPrefixProvider *dpp) override; + virtual const std::string get_name() const override { + return "rados"; + } + virtual std::string get_cluster_id(const DoutPrefixProvider* dpp, optional_yield y) override; + virtual std::unique_ptr 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) override; + virtual int get_user_by_email(const DoutPrefixProvider* dpp, const std::string& email, optional_yield y, std::unique_ptr* user) override; + virtual int get_user_by_swift(const DoutPrefixProvider* dpp, const std::string& user_str, optional_yield y, std::unique_ptr* user) override; + virtual std::unique_ptr get_object(const rgw_obj_key& k) override; + virtual int get_bucket(const DoutPrefixProvider* dpp, User* u, const rgw_bucket& b, std::unique_ptr* bucket, optional_yield y) override; + virtual int get_bucket(User* u, const RGWBucketInfo& i, std::unique_ptr* bucket) override; + virtual int get_bucket(const DoutPrefixProvider* dpp, User* u, const std::string& tenant, const std::string&name, std::unique_ptr* bucket, optional_yield y) override; + virtual bool is_meta_master() override; + virtual int forward_request_to_master(const DoutPrefixProvider *dpp, User* user, obj_version* objv, + bufferlist& in_data, JSONParser* jp, req_info& info, + optional_yield y) override; + virtual int forward_iam_request_to_master(const DoutPrefixProvider *dpp, const RGWAccessKey& key, obj_version* objv, + bufferlist& in_data, + RGWXMLDecoder::XMLParser* parser, req_info& info, + optional_yield y) override; + virtual Zone* get_zone() { return zone.get(); } + virtual std::string zone_unique_id(uint64_t unique_num) override; + virtual std::string zone_unique_trans_id(const uint64_t unique_num) override; + virtual int get_zonegroup(const std::string& id, std::unique_ptr* zonegroup) override; + virtual int list_all_zones(const DoutPrefixProvider* dpp, std::list& zone_ids) override; + virtual int cluster_stat(RGWClusterStat& stats) override; + virtual std::unique_ptr get_lifecycle(void) override; + virtual std::unique_ptr get_completions(void) override; + virtual std::unique_ptr get_notification(rgw::sal::Object* obj, rgw::sal::Object* src_obj, req_state* s, rgw::notify::EventType event_type, optional_yield y, const std::string* object_name=nullptr) override; + virtual std::unique_ptr get_notification( + const DoutPrefixProvider* dpp, rgw::sal::Object* obj, rgw::sal::Object* src_obj, + rgw::notify::EventType event_type, rgw::sal::Bucket* _bucket, std::string& _user_id, std::string& _user_tenant, + std::string& _req_id, optional_yield y) override; + int read_topics(const std::string& tenant, rgw_pubsub_topics& topics, RGWObjVersionTracker* objv_tracker, + optional_yield y, const DoutPrefixProvider *dpp) override; + int write_topics(const std::string& tenant, const rgw_pubsub_topics& topics, RGWObjVersionTracker* objv_tracker, + optional_yield y, const DoutPrefixProvider *dpp) override; + int remove_topics(const std::string& tenant, RGWObjVersionTracker* objv_tracker, + optional_yield y, const DoutPrefixProvider *dpp) override; + virtual RGWLC* get_rgwlc(void) override { return rados->get_lc(); } + virtual RGWCoroutinesManagerRegistry* get_cr_registry() override { return rados->get_cr_registry(); } + + virtual int log_usage(const DoutPrefixProvider *dpp, std::map& usage_info) override; + virtual int log_op(const DoutPrefixProvider *dpp, std::string& oid, bufferlist& bl) override; + virtual int register_to_service_map(const DoutPrefixProvider *dpp, const std::string& daemon_type, + const std::map& meta) override; + virtual void get_quota(RGWQuota& quota) override; + virtual void get_ratelimit(RGWRateLimitInfo& bucket_ratelimit, RGWRateLimitInfo& user_ratelimit, RGWRateLimitInfo& anon_ratelimit) override; + virtual int set_buckets_enabled(const DoutPrefixProvider* dpp, std::vector& buckets, bool enabled) override; + virtual int get_sync_policy_handler(const DoutPrefixProvider* dpp, + std::optional zone, + std::optional bucket, + RGWBucketSyncPolicyHandlerRef* phandler, + optional_yield y) override; + virtual RGWDataSyncStatusManager* get_data_sync_manager(const rgw_zone_id& source_zone) override; + virtual void wakeup_meta_sync_shards(std::set& shard_ids) override { rados->wakeup_meta_sync_shards(shard_ids); } + virtual void wakeup_data_sync_shards(const DoutPrefixProvider *dpp, const rgw_zone_id& source_zone, boost::container::flat_map>& shard_ids) override { rados->wakeup_data_sync_shards(dpp, source_zone, shard_ids); } + virtual int clear_usage(const DoutPrefixProvider *dpp) override { return rados->clear_usage(dpp); } + virtual int read_all_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; + virtual int trim_all_usage(const DoutPrefixProvider *dpp, uint64_t start_epoch, uint64_t end_epoch) override; + virtual int get_config_key_val(std::string name, bufferlist* bl) override; + virtual int meta_list_keys_init(const DoutPrefixProvider *dpp, const std::string& section, const std::string& marker, void** phandle) override; + virtual int meta_list_keys_next(const DoutPrefixProvider *dpp, void* handle, int max, std::list& keys, bool* truncated) override; + virtual void meta_list_keys_complete(void* handle) override; + virtual std::string meta_get_marker(void* handle) override; + virtual int meta_remove(const DoutPrefixProvider* dpp, std::string& metadata_key, optional_yield y) override; + virtual const RGWSyncModuleInstanceRef& get_sync_module() { return rados->get_sync_module(); } + virtual std::string get_host_id() { return rados->host_id; } + virtual std::unique_ptr get_lua_manager() override; + virtual std::unique_ptr get_role(std::string name, + std::string tenant, + std::string path="", + std::string trust_policy="", + std::string max_session_duration_str="", + std::multimap tags={}) override; + virtual std::unique_ptr get_role(std::string id) override; + virtual std::unique_ptr get_role(const RGWRoleInfo& info) override; + virtual int get_roles(const DoutPrefixProvider *dpp, + optional_yield y, + const std::string& path_prefix, + const std::string& tenant, + std::vector>& roles) override; + virtual std::unique_ptr get_oidc_provider() override; + virtual int get_oidc_providers(const DoutPrefixProvider *dpp, + const std::string& tenant, + std::vector>& providers) override; + virtual std::unique_ptr get_append_writer(const DoutPrefixProvider *dpp, + optional_yield y, + rgw::sal::Object* obj, + const rgw_user& owner, + const rgw_placement_rule *ptail_placement_rule, + const std::string& unique_tag, + uint64_t position, + uint64_t *cur_accounted_size) override; + virtual std::unique_ptr get_atomic_writer(const DoutPrefixProvider *dpp, + optional_yield y, + rgw::sal::Object* obj, + const rgw_user& owner, + const rgw_placement_rule *ptail_placement_rule, + uint64_t olh_epoch, + const std::string& unique_tag) override; + virtual const std::string& get_compression_type(const rgw_placement_rule& rule) override; + virtual bool valid_placement(const rgw_placement_rule& rule) override; + + virtual void finalize(void) override; + + virtual CephContext* ctx(void) override { return rados->ctx(); } + + virtual void register_admin_apis(RGWRESTMgr* mgr) override; + + /* Unique to RadosStore */ + int get_obj_head_ioctx(const DoutPrefixProvider *dpp, const RGWBucketInfo& bucket_info, const rgw_obj& obj, + librados::IoCtx* ioctx); + int delete_raw_obj(const DoutPrefixProvider *dpp, const rgw_raw_obj& obj); + int delete_raw_obj_aio(const DoutPrefixProvider *dpp, const rgw_raw_obj& obj, Completions* aio); + void get_raw_obj(const rgw_placement_rule& placement_rule, const rgw_obj& obj, rgw_raw_obj* raw_obj); + int get_raw_chunk_size(const DoutPrefixProvider* dpp, const rgw_raw_obj& obj, uint64_t* chunk_size); + + void setRados(RGWRados * st) { rados = st; } + RGWRados* getRados(void) { return rados; } + + RGWServices* svc() { return &rados->svc; } + const RGWServices* svc() const { return &rados->svc; } + RGWCtl* ctl() { return &rados->ctl; } + const RGWCtl* ctl() const { return &rados->ctl; } + + void setUserCtl(RGWUserCtl *_ctl) { user_ctl = _ctl; } +}; + +class RadosUser : public StoreUser { + private: + RadosStore* store; + + public: + RadosUser(RadosStore *_st, const rgw_user& _u) : StoreUser(_u), store(_st) { } + RadosUser(RadosStore *_st, const RGWUserInfo& _i) : StoreUser(_i), store(_st) { } + RadosUser(RadosStore *_st) : store(_st) { } + RadosUser(RadosUser& _o) = default; + + virtual std::unique_ptr clone() override { + return std::unique_ptr(new RadosUser(*this)); + } + int list_buckets(const DoutPrefixProvider* dpp, const std::string& marker, const std::string& end_marker, + uint64_t max, bool need_stats, BucketList& buckets, + optional_yield y) override; + virtual int create_bucket(const DoutPrefixProvider* dpp, + const rgw_bucket& b, + const std::string& zonegroup_id, + rgw_placement_rule& placement_rule, + std::string& swift_ver_location, + const RGWQuotaInfo * pquota_info, + const RGWAccessControlPolicy& policy, + Attrs& attrs, + RGWBucketInfo& info, + obj_version& ep_objv, + bool exclusive, + bool obj_lock_enabled, + bool* existed, + req_info& req_info, + std::unique_ptr* bucket, + optional_yield y) override; + 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_stats(const DoutPrefixProvider *dpp, + optional_yield y, RGWStorageStats* stats, + ceph::real_time* last_stats_sync = nullptr, + ceph::real_time* last_stats_update = nullptr) override; + virtual int read_stats_async(const DoutPrefixProvider *dpp, RGWGetUserStats_CB* cb) override; + virtual int complete_flush_stats(const DoutPrefixProvider *dpp, 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; + virtual int trim_usage(const DoutPrefixProvider *dpp, uint64_t start_epoch, uint64_t end_epoch) override; + + 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; + + friend class RadosBucket; +}; + +class RadosObject : public StoreObject { + private: + RadosStore* store; + RGWAccessControlPolicy acls; + RGWObjManifest *manifest{nullptr}; + RGWObjectCtx* rados_ctx; + bool rados_ctx_owned; + + public: + + struct RadosReadOp : public ReadOp { + private: + RadosObject* source; + RGWObjectCtx* rctx; + RGWRados::Object op_target; + RGWRados::Object::Read parent_op; + + public: + RadosReadOp(RadosObject *_source, RGWObjectCtx *_rctx); + + virtual int prepare(optional_yield y, const DoutPrefixProvider* dpp) override; + + /* + * Both `read` and `iterate` read up through index `end` + * *inclusive*. The number of bytes that could be returned is + * `end - ofs + 1`. + */ + virtual int read(int64_t ofs, int64_t end, + bufferlist& bl, optional_yield y, + const DoutPrefixProvider* dpp) override; + virtual int iterate(const DoutPrefixProvider* dpp, + int64_t ofs, int64_t end, + RGWGetDataCB* cb, optional_yield y) override; + + virtual int get_attr(const DoutPrefixProvider* dpp, const char* name, bufferlist& dest, optional_yield y) override; + }; + + struct RadosDeleteOp : public DeleteOp { + private: + RadosObject* source; + RGWRados::Object op_target; + RGWRados::Object::Delete parent_op; + + public: + RadosDeleteOp(RadosObject* _source); + + virtual int delete_obj(const DoutPrefixProvider* dpp, optional_yield y) override; + }; + + RadosObject(RadosStore *_st, const rgw_obj_key& _k) + : StoreObject(_k), + store(_st), + acls(), + rados_ctx(new RGWObjectCtx(dynamic_cast(store))), + rados_ctx_owned(true) { + } + RadosObject(RadosStore *_st, const rgw_obj_key& _k, Bucket* _b) + : StoreObject(_k, _b), + store(_st), + acls(), + rados_ctx(new RGWObjectCtx(dynamic_cast(store))) , + rados_ctx_owned(true) { + } + RadosObject(RadosObject& _o) : StoreObject(_o) { + store = _o.store; + acls = _o.acls; + manifest = _o.manifest; + rados_ctx = _o.rados_ctx; + rados_ctx_owned = false; + } + + virtual ~RadosObject(); + + virtual void invalidate() override { + StoreObject::invalidate(); + rados_ctx->invalidate(get_obj()); + } + virtual int delete_object(const DoutPrefixProvider* dpp, + optional_yield y, bool prevent_versioning) override; + virtual int delete_obj_aio(const DoutPrefixProvider* dpp, RGWObjState* astate, Completions* aio, + bool keep_index_consistent, optional_yield y) override; + virtual int copy_object(User* user, + req_info* info, const rgw_zone_id& source_zone, + rgw::sal::Object* dest_object, rgw::sal::Bucket* dest_bucket, + rgw::sal::Bucket* src_bucket, + const rgw_placement_rule& dest_placement, + ceph::real_time* src_mtime, ceph::real_time* mtime, + const ceph::real_time* mod_ptr, const ceph::real_time* unmod_ptr, + bool high_precision_time, + const char* if_match, const char* if_nomatch, + AttrsMod attrs_mod, bool copy_if_newer, Attrs& attrs, + RGWObjCategory category, uint64_t olh_epoch, + boost::optional delete_at, + std::string* version_id, std::string* tag, std::string* etag, + void (*progress_cb)(off_t, void *), void* progress_data, + const DoutPrefixProvider* dpp, optional_yield y) override; + virtual RGWAccessControlPolicy& get_acl(void) override { return acls; } + virtual int set_acl(const RGWAccessControlPolicy& acl) override { acls = acl; return 0; } + virtual void set_atomic() override { + rados_ctx->set_atomic(state.obj); + StoreObject::set_atomic(); + } + virtual void set_prefetch_data() override { + rados_ctx->set_prefetch_data(state.obj); + StoreObject::set_prefetch_data(); + } + virtual void set_compressed() override { + rados_ctx->set_compressed(state.obj); + StoreObject::set_compressed(); + } + + virtual int get_obj_state(const DoutPrefixProvider* dpp, RGWObjState **state, optional_yield y, bool follow_olh = true) override; + virtual int set_obj_attrs(const DoutPrefixProvider* dpp, Attrs* setattrs, Attrs* delattrs, optional_yield y) override; + virtual int get_obj_attrs(optional_yield y, const DoutPrefixProvider* dpp, rgw_obj* target_obj = NULL) override; + virtual int modify_obj_attrs(const char* attr_name, bufferlist& attr_val, optional_yield y, const DoutPrefixProvider* dpp) override; + virtual int delete_obj_attrs(const DoutPrefixProvider* dpp, const char* attr_name, optional_yield y) override; + virtual bool is_expired() override; + virtual void gen_rand_obj_instance_name() override; + void get_raw_obj(rgw_raw_obj* raw_obj); + virtual std::unique_ptr clone() override { + return std::unique_ptr(new RadosObject(*this)); + } + virtual std::unique_ptr get_serializer(const DoutPrefixProvider *dpp, + const std::string& lock_name) override; + virtual int transition(Bucket* bucket, + const rgw_placement_rule& placement_rule, + const real_time& mtime, + uint64_t olh_epoch, + const DoutPrefixProvider* dpp, + optional_yield y) override; + virtual int transition_to_cloud(Bucket* bucket, + rgw::sal::PlacementTier* tier, + rgw_bucket_dir_entry& o, + std::set& cloud_targets, + CephContext* cct, + bool update_object, + const DoutPrefixProvider* dpp, + optional_yield y) override; + virtual bool placement_rules_match(rgw_placement_rule& r1, rgw_placement_rule& r2) override; + virtual int dump_obj_layout(const DoutPrefixProvider *dpp, optional_yield y, Formatter* f) override; + + /* Swift versioning */ + virtual int swift_versioning_restore(bool& restored, + const DoutPrefixProvider* dpp) override; + virtual int swift_versioning_copy(const DoutPrefixProvider* dpp, + optional_yield y) override; + + /* OPs */ + virtual std::unique_ptr get_read_op() override; + virtual std::unique_ptr get_delete_op() override; + + /* OMAP */ + virtual int omap_get_vals(const DoutPrefixProvider *dpp, const std::string& marker, uint64_t count, + std::map *m, + bool* pmore, optional_yield y) override; + virtual int omap_get_all(const DoutPrefixProvider *dpp, std::map *m, + optional_yield y) override; + virtual int omap_get_vals_by_keys(const DoutPrefixProvider *dpp, const std::string& oid, + const std::set& keys, + Attrs* vals) override; + virtual int omap_set_val_by_key(const DoutPrefixProvider *dpp, const std::string& key, bufferlist& val, + bool must_exist, optional_yield y) override; + virtual int chown(User& new_user, const DoutPrefixProvider* dpp, optional_yield y) override; + + /* Internal to RadosStore */ + int get_max_chunk_size(const DoutPrefixProvider* dpp, + rgw_placement_rule placement_rule, + uint64_t* max_chunk_size, + uint64_t* alignment = nullptr); + void get_max_aligned_size(uint64_t size, uint64_t alignment, uint64_t* max_size); + void raw_obj_to_obj(const rgw_raw_obj& raw_obj); + int write_cloud_tier(const DoutPrefixProvider* dpp, + optional_yield y, + uint64_t olh_epoch, + rgw::sal::PlacementTier* tier, + bool is_multipart_upload, + rgw_placement_rule& target_placement, + Object* head_obj); + RGWObjManifest* get_manifest() { return manifest; } + RGWObjectCtx& get_ctx() { return *rados_ctx; } + + private: + int read_attrs(const DoutPrefixProvider* dpp, RGWRados::Object::Read &read_op, optional_yield y, rgw_obj* target_obj = nullptr); +}; + +class RadosBucket : public StoreBucket { + private: + RadosStore* store; + RGWAccessControlPolicy acls; + std::string topics_oid() const; + + public: + RadosBucket(RadosStore *_st) + : store(_st), + acls() { + } + + RadosBucket(RadosStore *_st, User* _u) + : StoreBucket(_u), + store(_st), + acls() { + } + + RadosBucket(RadosStore *_st, const rgw_bucket& _b) + : StoreBucket(_b), + store(_st), + acls() { + } + + RadosBucket(RadosStore *_st, const RGWBucketEnt& _e) + : StoreBucket(_e), + store(_st), + acls() { + } + + RadosBucket(RadosStore *_st, const RGWBucketInfo& _i) + : StoreBucket(_i), + store(_st), + acls() { + } + + RadosBucket(RadosStore *_st, const rgw_bucket& _b, User* _u) + : StoreBucket(_b, _u), + store(_st), + acls() { + } + + RadosBucket(RadosStore *_st, const RGWBucketEnt& _e, User* _u) + : StoreBucket(_e, _u), + store(_st), + acls() { + } + + RadosBucket(RadosStore *_st, const RGWBucketInfo& _i, User* _u) + : StoreBucket(_i, _u), + store(_st), + acls() { + } + + virtual ~RadosBucket(); + virtual std::unique_ptr get_object(const rgw_obj_key& k) override; + virtual int list(const DoutPrefixProvider* dpp, ListParams&, int, ListResults&, optional_yield y) override; + virtual int remove_bucket(const DoutPrefixProvider* dpp, bool delete_children, bool forward_to_master, req_info* req_info, optional_yield y) override; + virtual int remove_bucket_bypass_gc(int concurrent_max, bool + keep_index_consistent, + optional_yield y, const + DoutPrefixProvider *dpp) override; + virtual RGWAccessControlPolicy& get_acl(void) override { return acls; } + virtual int set_acl(const DoutPrefixProvider* dpp, RGWAccessControlPolicy& acl, optional_yield y) override; + virtual int load_bucket(const DoutPrefixProvider* dpp, optional_yield y, bool get_stats = false) override; + virtual int read_stats(const DoutPrefixProvider *dpp, + const bucket_index_layout_generation& idx_layout, + int shard_id, std::string* bucket_ver, std::string* master_ver, + std::map& stats, + std::string* max_marker = nullptr, + bool* syncstopped = nullptr) override; + virtual int read_stats_async(const DoutPrefixProvider *dpp, + const bucket_index_layout_generation& idx_layout, + int shard_id, RGWGetBucketStats_CB* ctx) override; + virtual int sync_user_stats(const DoutPrefixProvider *dpp, optional_yield y) override; + virtual int update_container_stats(const DoutPrefixProvider* dpp) override; + virtual int check_bucket_shards(const DoutPrefixProvider* dpp) override; + virtual int chown(const DoutPrefixProvider* dpp, User& new_user, optional_yield y) override; + virtual int put_info(const DoutPrefixProvider* dpp, bool exclusive, ceph::real_time mtime) override; + virtual bool is_owner(User* user) override; + virtual int check_empty(const DoutPrefixProvider* dpp, optional_yield y) override; + virtual int check_quota(const DoutPrefixProvider *dpp, RGWQuota& quota, uint64_t obj_size, optional_yield y, bool check_size_only = false) override; + virtual int merge_and_store_attrs(const DoutPrefixProvider* dpp, Attrs& attrs, optional_yield y) override; + virtual int try_refresh_info(const DoutPrefixProvider* dpp, ceph::real_time* pmtime) 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; + virtual int trim_usage(const DoutPrefixProvider *dpp, uint64_t start_epoch, uint64_t end_epoch) override; + virtual int remove_objs_from_index(const DoutPrefixProvider *dpp, std::list& objs_to_unlink) override; + virtual int check_index(const DoutPrefixProvider *dpp, std::map& existing_stats, std::map& calculated_stats) override; + virtual int rebuild_index(const DoutPrefixProvider *dpp) override; + virtual int set_tag_timeout(const DoutPrefixProvider *dpp, uint64_t timeout) override; + virtual int purge_instance(const DoutPrefixProvider* dpp) override; + virtual std::unique_ptr clone() override { + return std::make_unique(*this); + } + virtual std::unique_ptr get_multipart_upload( + const std::string& oid, + std::optional upload_id=std::nullopt, + ACLOwner owner={}, ceph::real_time mtime=real_clock::now()) override; + virtual int list_multiparts(const DoutPrefixProvider *dpp, + const std::string& prefix, + std::string& marker, + const std::string& delim, + const int& max_uploads, + std::vector>& uploads, + std::map *common_prefixes, + bool *is_truncated) override; + virtual int abort_multiparts(const DoutPrefixProvider* dpp, + CephContext* cct) override; + int read_topics(rgw_pubsub_bucket_topics& notifications, RGWObjVersionTracker* objv_tracker, + optional_yield y, const DoutPrefixProvider *dpp) override; + int write_topics(const rgw_pubsub_bucket_topics& notifications, RGWObjVersionTracker* objv_tracker, + optional_yield y, const DoutPrefixProvider *dpp) override; + int remove_topics(RGWObjVersionTracker* objv_tracker, + optional_yield y, const DoutPrefixProvider *dpp) override; + + private: + int link(const DoutPrefixProvider* dpp, User* new_user, optional_yield y, bool update_entrypoint = true, RGWObjVersionTracker* objv = nullptr); + int unlink(const DoutPrefixProvider* dpp, User* new_user, optional_yield y, bool update_entrypoint = true); + friend class RadosUser; +}; + +class RadosMultipartPart : public StoreMultipartPart { +protected: + RGWUploadPartInfo info; + +public: + RadosMultipartPart() = default; + virtual ~RadosMultipartPart() = default; + + virtual uint32_t get_num() { return info.num; } + virtual uint64_t get_size() { return info.accounted_size; } + virtual const std::string& get_etag() { return info.etag; } + virtual ceph::real_time& get_mtime() { return info.modified; } + + /* For RadosStore code */ + RGWObjManifest& get_manifest() { return info.manifest; } + const std::set& get_past_prefixes() const { return info.past_prefixes; } + + friend class RadosMultipartUpload; +}; + +class RadosMultipartUpload : public StoreMultipartUpload { + RadosStore* store; + RGWMPObj mp_obj; + ACLOwner owner; + ceph::real_time mtime; + rgw_placement_rule placement; + RGWObjManifest manifest; + +public: + RadosMultipartUpload(RadosStore* _store, Bucket* _bucket, const std::string& oid, + std::optional upload_id, ACLOwner owner, + ceph::real_time _mtime) + : StoreMultipartUpload(_bucket), store(_store), mp_obj(oid, upload_id), + owner(owner), mtime(_mtime) {} + virtual ~RadosMultipartUpload() = default; + + virtual const std::string& get_meta() const override { return mp_obj.get_meta(); } + virtual const std::string& get_key() const override { return mp_obj.get_key(); } + virtual const std::string& get_upload_id() const override { return mp_obj.get_upload_id(); } + virtual const ACLOwner& get_owner() const override { return owner; } + virtual ceph::real_time& get_mtime() override { return mtime; } + virtual std::unique_ptr get_meta_obj() override; + virtual int init(const DoutPrefixProvider* dpp, optional_yield y, ACLOwner& owner, rgw_placement_rule& dest_placement, rgw::sal::Attrs& attrs) override; + virtual int list_parts(const DoutPrefixProvider* dpp, CephContext* cct, + int num_parts, int marker, + int* next_marker, bool* truncated, + bool assume_unsorted = false) override; + virtual int abort(const DoutPrefixProvider* dpp, CephContext* cct) override; + virtual int complete(const DoutPrefixProvider* dpp, + optional_yield y, CephContext* cct, + std::map& part_etags, + std::list& remove_objs, + uint64_t& accounted_size, bool& compressed, + RGWCompressionInfo& cs_info, off_t& ofs, + std::string& tag, ACLOwner& owner, + uint64_t olh_epoch, + rgw::sal::Object* target_obj) override; + virtual int get_info(const DoutPrefixProvider *dpp, optional_yield y, rgw_placement_rule** rule, rgw::sal::Attrs* attrs = nullptr) override; + virtual std::unique_ptr get_writer(const DoutPrefixProvider *dpp, + optional_yield y, + rgw::sal::Object* obj, + const rgw_user& owner, + const rgw_placement_rule *ptail_placement_rule, + uint64_t part_num, + const std::string& part_num_str) override; +protected: + int cleanup_part_history(const DoutPrefixProvider* dpp, + optional_yield y, + RadosMultipartPart* part, + std::list& remove_objs); +}; + +class MPRadosSerializer : public StoreMPSerializer { + librados::IoCtx ioctx; + rados::cls::lock::Lock lock; + librados::ObjectWriteOperation op; + +public: + MPRadosSerializer(const DoutPrefixProvider *dpp, RadosStore* store, RadosObject* obj, const std::string& lock_name); + + virtual int try_lock(const DoutPrefixProvider *dpp, utime_t dur, optional_yield y) override; + virtual int unlock() override { + return lock.unlock(&ioctx, oid); + } +}; + +class LCRadosSerializer : public StoreLCSerializer { + librados::IoCtx* ioctx; + rados::cls::lock::Lock lock; + +public: + LCRadosSerializer(RadosStore* 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; + virtual int unlock() override { + return lock.unlock(ioctx, oid); + } +}; + +class RadosLifecycle : public StoreLifecycle { + RadosStore* store; + +public: + RadosLifecycle(RadosStore* _st) : store(_st) {} + + using StoreLifecycle::get_entry; + virtual int get_entry(const std::string& oid, const std::string& marker, std::unique_ptr* entry) override; + virtual int get_next_entry(const std::string& oid, const std::string& marker, std::unique_ptr* entry) override; + virtual int set_entry(const std::string& oid, LCEntry& entry) override; + virtual int list_entries(const std::string& oid, const std::string& marker, + uint32_t max_entries, + std::vector>& entries) override; + virtual int rm_entry(const std::string& oid, LCEntry& entry) override; + virtual int get_head(const std::string& oid, std::unique_ptr* head) override; + virtual int put_head(const std::string& oid, LCHead& head) override; + virtual std::unique_ptr get_serializer(const std::string& lock_name, + const std::string& oid, + const std::string& cookie) override; +}; + +class RadosNotification : public StoreNotification { + RadosStore* store; + /* XXX it feels incorrect to me that rgw::notify::reservation_t is + * currently RADOS-specific; instead, I think notification types such as + * reservation_t should be generally visible, whereas the internal + * notification behavior should be made portable (e.g., notification + * to non-RADOS message sinks) */ + rgw::notify::reservation_t res; + + public: + RadosNotification(const DoutPrefixProvider* _dpp, RadosStore* _store, Object* _obj, Object* _src_obj, req_state* _s, rgw::notify::EventType _type, optional_yield y, const std::string* object_name) : + StoreNotification(_obj, _src_obj, _type), store(_store), res(_dpp, _store, _s, _obj, _src_obj, object_name, y) { } + + RadosNotification(const DoutPrefixProvider* _dpp, RadosStore* _store, Object* _obj, Object* _src_obj, rgw::notify::EventType _type, rgw::sal::Bucket* _bucket, std::string& _user_id, std::string& _user_tenant, std::string& _req_id, optional_yield y) : + StoreNotification(_obj, _src_obj, _type), store(_store), res(_dpp, _store, _obj, _src_obj, _bucket, _user_id, _user_tenant, _req_id, y) {} + + ~RadosNotification() = default; + + rgw::notify::reservation_t& get_reservation(void) { + return res; + } + + virtual int publish_reserve(const DoutPrefixProvider *dpp, RGWObjTags* obj_tags = nullptr) override; + virtual int publish_commit(const DoutPrefixProvider* dpp, uint64_t size, + const ceph::real_time& mtime, const std::string& etag, const std::string& version) override; +}; + +class RadosAtomicWriter : public StoreWriter { +protected: + rgw::sal::RadosStore* store; + std::unique_ptr aio; + RGWObjectCtx& obj_ctx; + rgw::putobj::AtomicObjectProcessor processor; + +public: + RadosAtomicWriter(const DoutPrefixProvider *dpp, + optional_yield y, + RGWBucketInfo& bucket_info, + RGWObjectCtx& obj_ctx, + const rgw_obj& obj, + RadosStore* _store, std::unique_ptr _aio, + const rgw_user& owner, + const rgw_placement_rule *ptail_placement_rule, + uint64_t olh_epoch, + const std::string& unique_tag) : + StoreWriter(dpp, y), + store(_store), + aio(std::move(_aio)), + obj_ctx(obj_ctx), + processor(&*aio, store->getRados(), bucket_info, + ptail_placement_rule, owner, obj_ctx, + obj, olh_epoch, unique_tag, + dpp, y) + {} + ~RadosAtomicWriter() = default; + + // prepare to start processing object data + virtual int prepare(optional_yield y) override; + + // Process a bufferlist + virtual int process(bufferlist&& data, uint64_t offset) override; + + // complete the operation and make its result visible to clients + virtual int complete(size_t accounted_size, const std::string& etag, + ceph::real_time *mtime, ceph::real_time set_mtime, + std::map& attrs, + ceph::real_time delete_at, + const char *if_match, const char *if_nomatch, + const std::string *user_data, + rgw_zone_set *zones_trace, bool *canceled, + optional_yield y) override; +}; + +class RadosAppendWriter : public StoreWriter { +protected: + rgw::sal::RadosStore* store; + std::unique_ptr aio; + RGWObjectCtx& obj_ctx; + rgw::putobj::AppendObjectProcessor processor; + +public: + RadosAppendWriter(const DoutPrefixProvider *dpp, + optional_yield y, + RGWBucketInfo& bucket_info, + RGWObjectCtx& obj_ctx, + const rgw_obj& obj, + RadosStore* _store, std::unique_ptr _aio, + const rgw_user& owner, + const rgw_placement_rule *ptail_placement_rule, + const std::string& unique_tag, + uint64_t position, + uint64_t *cur_accounted_size) : + StoreWriter(dpp, y), + store(_store), + aio(std::move(_aio)), + obj_ctx(obj_ctx), + processor(&*aio, store->getRados(), bucket_info, + ptail_placement_rule, owner, obj_ctx, + obj, unique_tag, position, + cur_accounted_size, dpp, y) + {} + ~RadosAppendWriter() = default; + + // prepare to start processing object data + virtual int prepare(optional_yield y) override; + + // Process a bufferlist + virtual int process(bufferlist&& data, uint64_t offset) override; + + // complete the operation and make its result visible to clients + virtual int complete(size_t accounted_size, const std::string& etag, + ceph::real_time *mtime, ceph::real_time set_mtime, + std::map& attrs, + ceph::real_time delete_at, + const char *if_match, const char *if_nomatch, + const std::string *user_data, + rgw_zone_set *zones_trace, bool *canceled, + optional_yield y) override; +}; + +class RadosMultipartWriter : public StoreWriter { +protected: + rgw::sal::RadosStore* store; + std::unique_ptr aio; + RGWObjectCtx& obj_ctx; + rgw::putobj::MultipartObjectProcessor processor; + +public: + RadosMultipartWriter(const DoutPrefixProvider *dpp, + optional_yield y, const std::string& upload_id, + RGWBucketInfo& bucket_info, + RGWObjectCtx& obj_ctx, + const rgw_obj& obj, + RadosStore* _store, std::unique_ptr _aio, + const rgw_user& owner, + const rgw_placement_rule *ptail_placement_rule, + uint64_t part_num, const std::string& part_num_str) : + StoreWriter(dpp, y), + store(_store), + aio(std::move(_aio)), + obj_ctx(obj_ctx), + processor(&*aio, store->getRados(), bucket_info, + ptail_placement_rule, owner, obj_ctx, + obj, upload_id, + part_num, part_num_str, dpp, y) + {} + ~RadosMultipartWriter() = default; + + // prepare to start processing object data + virtual int prepare(optional_yield y) override; + + // Process a bufferlist + virtual int process(bufferlist&& data, uint64_t offset) override; + + // complete the operation and make its result visible to clients + virtual int complete(size_t accounted_size, const std::string& etag, + ceph::real_time *mtime, ceph::real_time set_mtime, + std::map& attrs, + ceph::real_time delete_at, + const char *if_match, const char *if_nomatch, + const std::string *user_data, + rgw_zone_set *zones_trace, bool *canceled, + optional_yield y) override; +}; + +class RadosLuaManager : public StoreLuaManager { + RadosStore* const store; + rgw_pool pool; + +public: + RadosLuaManager(RadosStore* _s); + virtual ~RadosLuaManager() = default; + + virtual int get_script(const DoutPrefixProvider* dpp, optional_yield y, const std::string& key, std::string& script); + virtual int put_script(const DoutPrefixProvider* dpp, optional_yield y, const std::string& key, const std::string& script); + virtual int del_script(const DoutPrefixProvider* dpp, optional_yield y, const std::string& key); + virtual int add_package(const DoutPrefixProvider* dpp, optional_yield y, const std::string& package_name); + virtual int remove_package(const DoutPrefixProvider* dpp, optional_yield y, const std::string& package_name); + virtual int list_packages(const DoutPrefixProvider* dpp, optional_yield y, rgw::lua::packages_t& packages); +}; + +class RadosOIDCProvider : public RGWOIDCProvider { + RadosStore* store; +public: + RadosOIDCProvider(RadosStore* _store) : store(_store) {} + ~RadosOIDCProvider() = default; + + virtual int store_url(const DoutPrefixProvider *dpp, const std::string& url, bool exclusive, optional_yield y) override; + virtual int read_url(const DoutPrefixProvider *dpp, const std::string& url, const std::string& tenant) override; + virtual int delete_obj(const DoutPrefixProvider *dpp, optional_yield y) override; + void encode(bufferlist& bl) const { + RGWOIDCProvider::encode(bl); + } + void decode(bufferlist::const_iterator& bl) { + RGWOIDCProvider::decode(bl); + } +}; + +class RadosRole : public RGWRole { + RadosStore* store; +public: + RadosRole(RadosStore* _store, std::string name, + std::string tenant, + std::string path, + std::string trust_policy, + std::string max_session_duration, + std::multimap tags) : RGWRole(name, tenant, path, trust_policy, max_session_duration, tags), store(_store) {} + RadosRole(RadosStore* _store, std::string id) : RGWRole(id), store(_store) {} + RadosRole(RadosStore* _store, const RGWRoleInfo& info) : RGWRole(info), store(_store) {} + RadosRole(RadosStore* _store) : store(_store) {} + ~RadosRole() = default; + + virtual int store_info(const DoutPrefixProvider *dpp, bool exclusive, optional_yield y) override; + virtual int store_name(const DoutPrefixProvider *dpp, bool exclusive, optional_yield y) override; + virtual int store_path(const DoutPrefixProvider *dpp, bool exclusive, optional_yield y) override; + virtual int read_id(const DoutPrefixProvider *dpp, const std::string& role_name, const std::string& tenant, std::string& role_id, optional_yield y) override; + virtual int read_name(const DoutPrefixProvider *dpp, optional_yield y) override; + virtual int read_info(const DoutPrefixProvider *dpp, optional_yield y) override; + virtual int create(const DoutPrefixProvider *dpp, bool exclusive, const std::string& role_id, optional_yield y) override; + virtual int delete_obj(const DoutPrefixProvider *dpp, optional_yield y) override; +}; +}} // namespace rgw::sal + +WRITE_CLASS_ENCODER(rgw::sal::RadosOIDCProvider) -- cgit v1.2.3