1 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2 // vim: ts=8 sw=2 smarttab ft=cpp
5 * Ceph - scalable distributed file system
7 * Copyright (C) 2020 Red Hat, Inc.
9 * This is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Lesser General Public
11 * License version 2.1, as published by the Free Software
12 * Foundation. See file COPYING.
19 #include "rgw_rados.h"
20 #include "cls/lock/cls_lock_client.h"
22 namespace rgw
{ namespace sal
{
26 class RGWRadosUser
: public RGWUser
{
31 RGWRadosUser(RGWRadosStore
*_st
, const rgw_user
& _u
) : RGWUser(_u
), store(_st
) { }
32 RGWRadosUser(RGWRadosStore
*_st
, const RGWUserInfo
& _i
) : RGWUser(_i
), store(_st
) { }
33 RGWRadosUser(RGWRadosStore
*_st
) : store(_st
) { }
36 int list_buckets(const DoutPrefixProvider
*dpp
, const std::string
& marker
, const std::string
& end_marker
,
37 uint64_t max
, bool need_stats
, RGWBucketList
& buckets
,
38 optional_yield y
) override
;
39 RGWBucket
* create_bucket(rgw_bucket
& bucket
, ceph::real_time creation_time
);
42 virtual int load_by_id(const DoutPrefixProvider
*dpp
, optional_yield y
);
44 friend class RGWRadosBucket
;
47 class RGWRadosObject
: public RGWObject
{
50 RGWAccessControlPolicy acls
;
54 struct RadosReadOp
: public ReadOp
{
56 RGWRadosObject
* source
;
58 RGWRados::Object op_target
;
59 RGWRados::Object::Read parent_op
;
62 RadosReadOp(RGWRadosObject
*_source
, RGWObjectCtx
*_rctx
);
64 virtual int prepare(optional_yield y
, const DoutPrefixProvider
*dpp
) override
;
65 virtual int read(int64_t ofs
, int64_t end
, bufferlist
& bl
, optional_yield y
, const DoutPrefixProvider
*dpp
) override
;
66 virtual int iterate(const DoutPrefixProvider
*dpp
, int64_t ofs
, int64_t end
, RGWGetDataCB
*cb
, optional_yield y
) override
;
67 virtual int get_manifest(const DoutPrefixProvider
*dpp
, RGWObjManifest
**pmanifest
, optional_yield y
) override
;
68 virtual int get_attr(const DoutPrefixProvider
*dpp
, const char *name
, bufferlist
& dest
, optional_yield y
) override
;
71 struct RadosWriteOp
: public WriteOp
{
73 RGWRadosObject
* source
;
75 RGWRados::Object op_target
;
76 RGWRados::Object::Write parent_op
;
79 RadosWriteOp(RGWRadosObject
* _source
, RGWObjectCtx
* _rctx
);
81 virtual int prepare(optional_yield y
) override
;
82 virtual int write_meta(const DoutPrefixProvider
*dpp
, uint64_t size
, uint64_t accounted_size
, optional_yield y
) override
;
83 //virtual int write_data(const char *data, uint64_t ofs, uint64_t len, bool exclusive) override;
86 RGWRadosObject() = default;
88 RGWRadosObject(RGWRadosStore
*_st
, const rgw_obj_key
& _k
)
93 RGWRadosObject(RGWRadosStore
*_st
, const rgw_obj_key
& _k
, RGWBucket
* _b
)
98 RGWRadosObject(RGWRadosObject
& _o
) = default;
100 int read(off_t offset
, off_t length
, std::iostream
& stream
) { return length
; }
101 int write(off_t offset
, off_t length
, std::iostream
& stream
) { return length
; }
102 virtual int delete_object(const DoutPrefixProvider
*dpp
, RGWObjectCtx
* obj_ctx
, ACLOwner obj_owner
,
103 ACLOwner bucket_owner
, ceph::real_time unmod_since
,
104 bool high_precision_time
, uint64_t epoch
,
105 std::string
& version_id
,
107 bool prevent_versioning
) override
;
108 virtual int copy_object(RGWObjectCtx
& obj_ctx
, RGWUser
* user
,
109 req_info
*info
, const rgw_zone_id
& source_zone
,
110 rgw::sal::RGWObject
* dest_object
, rgw::sal::RGWBucket
* dest_bucket
,
111 rgw::sal::RGWBucket
* src_bucket
,
112 const rgw_placement_rule
& dest_placement
,
113 ceph::real_time
*src_mtime
, ceph::real_time
*mtime
,
114 const ceph::real_time
*mod_ptr
, const ceph::real_time
*unmod_ptr
,
115 bool high_precision_time
,
116 const char *if_match
, const char *if_nomatch
,
117 AttrsMod attrs_mod
, bool copy_if_newer
, RGWAttrs
& attrs
,
118 RGWObjCategory category
, uint64_t olh_epoch
,
119 boost::optional
<ceph::real_time
> delete_at
,
120 string
*version_id
, string
*tag
, string
*etag
,
121 void (*progress_cb
)(off_t
, void *), void *progress_data
,
122 const DoutPrefixProvider
*dpp
, optional_yield y
) override
;
123 RGWAccessControlPolicy
& get_acl(void) { return acls
; }
124 int set_acl(const RGWAccessControlPolicy
& acl
) { acls
= acl
; return 0; }
125 virtual void set_atomic(RGWObjectCtx
*rctx
) const;
126 virtual void set_prefetch_data(RGWObjectCtx
*rctx
);
128 virtual int get_obj_state(const DoutPrefixProvider
*dpp
, RGWObjectCtx
*rctx
, RGWBucket
& bucket
, RGWObjState
**state
, optional_yield y
, bool follow_olh
= true) override
;
129 virtual int set_obj_attrs(const DoutPrefixProvider
*dpp
, RGWObjectCtx
* rctx
, RGWAttrs
* setattrs
, RGWAttrs
* delattrs
, optional_yield y
, rgw_obj
* target_obj
= NULL
) override
;
130 virtual int get_obj_attrs(RGWObjectCtx
*rctx
, optional_yield y
, const DoutPrefixProvider
*dpp
, rgw_obj
* target_obj
= NULL
) override
;
131 virtual int modify_obj_attrs(RGWObjectCtx
*rctx
, const char *attr_name
, bufferlist
& attr_val
, optional_yield y
, const DoutPrefixProvider
*dpp
) override
;
132 virtual int delete_obj_attrs(const DoutPrefixProvider
*dpp
, RGWObjectCtx
*rctx
, const char *attr_name
, optional_yield y
) override
;
133 virtual int copy_obj_data(RGWObjectCtx
& rctx
, RGWBucket
* dest_bucket
, RGWObject
* dest_obj
, uint16_t olh_epoch
, std::string
* petag
, const DoutPrefixProvider
*dpp
, optional_yield y
) override
;
134 virtual bool is_expired() override
;
135 virtual void gen_rand_obj_instance_name() override
;
136 virtual void raw_obj_to_obj(const rgw_raw_obj
& raw_obj
) override
;
137 virtual void get_raw_obj(rgw_raw_obj
* raw_obj
) override
;
138 virtual std::unique_ptr
<RGWObject
> clone() {
139 return std::unique_ptr
<RGWObject
>(new RGWRadosObject(*this));
141 virtual MPSerializer
* get_serializer(const DoutPrefixProvider
*dpp
, const std::string
& lock_name
) override
;
142 virtual int transition(RGWObjectCtx
& rctx
,
144 const rgw_placement_rule
& placement_rule
,
145 const real_time
& mtime
,
147 const DoutPrefixProvider
*dpp
,
148 optional_yield y
) override
;
149 virtual int get_max_chunk_size(const DoutPrefixProvider
*dpp
,
150 rgw_placement_rule placement_rule
,
151 uint64_t *max_chunk_size
,
152 uint64_t *alignment
= nullptr) override
;
153 virtual void get_max_aligned_size(uint64_t size
, uint64_t alignment
, uint64_t *max_size
) override
;
154 virtual bool placement_rules_match(rgw_placement_rule
& r1
, rgw_placement_rule
& r2
) override
;
156 /* Swift versioning */
157 virtual int swift_versioning_restore(RGWObjectCtx
* obj_ctx
,
159 const DoutPrefixProvider
*dpp
) override
;
160 virtual int swift_versioning_copy(RGWObjectCtx
* obj_ctx
,
161 const DoutPrefixProvider
*dpp
,
162 optional_yield y
) override
;
165 virtual std::unique_ptr
<ReadOp
> get_read_op(RGWObjectCtx
*) override
;
166 virtual std::unique_ptr
<WriteOp
> get_write_op(RGWObjectCtx
*) override
;
169 virtual int omap_get_vals_by_keys(const DoutPrefixProvider
*dpp
, const std::string
& oid
,
170 const std::set
<std::string
>& keys
,
171 RGWAttrs
*vals
) override
;
172 virtual int omap_set_val_by_key(const DoutPrefixProvider
*dpp
, const std::string
& key
, bufferlist
& val
,
173 bool must_exist
, optional_yield y
) override
;
176 int read_attrs(RGWRados::Object::Read
&read_op
, optional_yield y
, const DoutPrefixProvider
*dpp
, rgw_obj
*target_obj
= nullptr);
179 class RGWRadosBucket
: public RGWBucket
{
181 RGWRadosStore
*store
;
182 RGWAccessControlPolicy acls
;
185 RGWRadosBucket(RGWRadosStore
*_st
)
190 RGWRadosBucket(RGWRadosStore
*_st
, const rgw_bucket
& _b
)
196 RGWRadosBucket(RGWRadosStore
*_st
, const RGWBucketEnt
& _e
)
202 RGWRadosBucket(RGWRadosStore
*_st
, const RGWBucketInfo
& _i
)
208 RGWRadosBucket(RGWRadosStore
*_st
, const rgw_bucket
& _b
, RGWUser
* _u
)
214 RGWRadosBucket(RGWRadosStore
*_st
, const RGWBucketEnt
& _e
, RGWUser
* _u
)
220 RGWRadosBucket(RGWRadosStore
*_st
, const RGWBucketInfo
& _i
, RGWUser
* _u
)
226 ~RGWRadosBucket() { }
228 virtual int load_by_name(const DoutPrefixProvider
*dpp
, const std::string
& tenant
, const std::string
& bucket_name
, const std::string bucket_instance_id
, RGWSysObjectCtx
*rctx
, optional_yield y
) override
;
229 virtual std::unique_ptr
<RGWObject
> get_object(const rgw_obj_key
& k
) override
;
230 RGWBucketList
* list(void) { return new RGWBucketList(); }
231 virtual int list(const DoutPrefixProvider
*dpp
, ListParams
&, int, ListResults
&, optional_yield y
) override
;
232 RGWObject
* create_object(const rgw_obj_key
& key
/* Attributes */) override
;
233 virtual int remove_bucket(const DoutPrefixProvider
*dpp
, bool delete_children
, std::string prefix
, std::string delimiter
, bool forward_to_master
, req_info
* req_info
, optional_yield y
) override
;
234 RGWAccessControlPolicy
& get_acl(void) { return acls
; }
235 virtual int set_acl(const DoutPrefixProvider
*dpp
, RGWAccessControlPolicy
& acl
, optional_yield y
) override
;
236 virtual int get_bucket_info(const DoutPrefixProvider
*dpp
, optional_yield y
) override
;
237 virtual int get_bucket_stats(const DoutPrefixProvider
*dpp
, RGWBucketInfo
& bucket_info
, int shard_id
,
238 std::string
*bucket_ver
, std::string
*master_ver
,
239 std::map
<RGWObjCategory
, RGWStorageStats
>& stats
,
240 std::string
*max_marker
= nullptr,
241 bool *syncstopped
= nullptr) override
;
242 virtual int read_bucket_stats(const DoutPrefixProvider
*dpp
, optional_yield y
) override
;
243 virtual int sync_user_stats(const DoutPrefixProvider
*dpp
, optional_yield y
) override
;
244 virtual int update_container_stats(const DoutPrefixProvider
*dpp
) override
;
245 virtual int check_bucket_shards(const DoutPrefixProvider
*dpp
) override
;
246 virtual int link(const DoutPrefixProvider
*dpp
, RGWUser
* new_user
, optional_yield y
) override
;
247 virtual int unlink(RGWUser
* new_user
, optional_yield y
) override
;
248 virtual int chown(RGWUser
* new_user
, RGWUser
* old_user
, optional_yield y
, const DoutPrefixProvider
*dpp
) override
;
249 virtual int put_instance_info(const DoutPrefixProvider
*dpp
, bool exclusive
, ceph::real_time mtime
) override
;
250 virtual bool is_owner(RGWUser
* user
) override
;
251 virtual int check_empty(const DoutPrefixProvider
*dpp
, optional_yield y
) override
;
252 virtual int check_quota(RGWQuotaInfo
& user_quota
, RGWQuotaInfo
& bucket_quota
, uint64_t obj_size
, optional_yield y
, bool check_size_only
= false) override
;
253 virtual int set_instance_attrs(const DoutPrefixProvider
*dpp
, RGWAttrs
& attrs
, optional_yield y
) override
;
254 virtual int try_refresh_info(const DoutPrefixProvider
*dpp
, ceph::real_time
*pmtime
) override
;
255 virtual int read_usage(const DoutPrefixProvider
*dpp
, uint64_t start_epoch
, uint64_t end_epoch
, uint32_t max_entries
,
256 bool *is_truncated
, RGWUsageIter
& usage_iter
,
257 map
<rgw_user_bucket
, rgw_usage_log_entry
>& usage
) override
;
258 virtual std::unique_ptr
<RGWBucket
> clone() {
259 return std::make_unique
<RGWRadosBucket
>(*this);
262 friend class RGWRadosStore
;
265 class RGWRadosStore
: public RGWStore
{
268 RGWUserCtl
*user_ctl
;
269 std::string luarocks_path
;
279 virtual std::unique_ptr
<RGWUser
> get_user(const rgw_user
& u
);
280 virtual std::unique_ptr
<RGWObject
> get_object(const rgw_obj_key
& k
) override
;
281 virtual int get_bucket(const DoutPrefixProvider
*dpp
, RGWUser
* u
, const rgw_bucket
& b
, std::unique_ptr
<RGWBucket
>* bucket
, optional_yield y
) override
;
282 virtual int get_bucket(RGWUser
* u
, const RGWBucketInfo
& i
, std::unique_ptr
<RGWBucket
>* bucket
) override
;
283 virtual int get_bucket(const DoutPrefixProvider
*dpp
, RGWUser
* u
, const std::string
& tenant
, const std::string
&name
, std::unique_ptr
<RGWBucket
>* bucket
, optional_yield y
) override
;
284 virtual int create_bucket(const DoutPrefixProvider
*dpp
,
285 RGWUser
& u
, const rgw_bucket
& b
,
286 const std::string
& zonegroup_id
,
287 rgw_placement_rule
& placement_rule
,
288 std::string
& swift_ver_location
,
289 const RGWQuotaInfo
* pquota_info
,
290 const RGWAccessControlPolicy
& policy
,
293 obj_version
& ep_objv
,
295 bool obj_lock_enabled
,
298 std::unique_ptr
<RGWBucket
>* bucket
,
300 virtual RGWBucketList
* list_buckets(void) { return new RGWBucketList(); }
301 virtual bool is_meta_master() override
;
302 virtual int forward_request_to_master(const DoutPrefixProvider
*dpp
, RGWUser
* user
, obj_version
*objv
,
303 bufferlist
& in_data
, JSONParser
*jp
, req_info
& info
,
304 optional_yield y
) override
;
305 virtual int defer_gc(const DoutPrefixProvider
*dpp
, RGWObjectCtx
*rctx
, RGWBucket
* bucket
, RGWObject
* obj
,
306 optional_yield y
) override
;
307 virtual const RGWZoneGroup
& get_zonegroup() override
;
308 virtual int get_zonegroup(const string
& id
, RGWZoneGroup
& zonegroup
) override
;
309 virtual int cluster_stat(RGWClusterStat
& stats
) override
;
310 virtual std::unique_ptr
<Lifecycle
> get_lifecycle(void) override
;
311 virtual RGWLC
* get_rgwlc(void) { return rados
->get_lc(); }
312 virtual int delete_raw_obj(const DoutPrefixProvider
*dpp
, const rgw_raw_obj
& obj
) override
;
313 virtual void get_raw_obj(const rgw_placement_rule
& placement_rule
, const rgw_obj
& obj
, rgw_raw_obj
* raw_obj
) override
;
314 virtual int get_raw_chunk_size(const DoutPrefixProvider
*dpp
, const rgw_raw_obj
& obj
, uint64_t* chunk_size
) override
;
316 void setRados(RGWRados
* st
) { rados
= st
; }
317 RGWRados
*getRados(void) { return rados
; }
319 RGWServices
*svc() { return &rados
->svc
; }
320 const RGWServices
*svc() const { return &rados
->svc
; }
321 RGWCtl
*ctl() { return &rados
->ctl
; }
322 const RGWCtl
*ctl() const { return &rados
->ctl
; }
324 void setUserCtl(RGWUserCtl
*_ctl
) { user_ctl
= _ctl
; }
326 void finalize(void) override
;
328 virtual CephContext
*ctx(void) { return rados
->ctx(); }
331 int get_obj_head_ioctx(const DoutPrefixProvider
*dpp
, const RGWBucketInfo
& bucket_info
, const rgw_obj
& obj
,
332 librados::IoCtx
*ioctx
);
334 const std::string
& get_luarocks_path() const override
{
335 return luarocks_path
;
338 void set_luarocks_path(const std::string
& path
) override
{
339 luarocks_path
= path
;
343 class MPRadosSerializer
: public MPSerializer
{
344 librados::IoCtx ioctx
;
345 rados::cls::lock::Lock lock
;
346 librados::ObjectWriteOperation op
;
349 MPRadosSerializer(const DoutPrefixProvider
*dpp
, RGWRadosStore
* store
, RGWRadosObject
* obj
, const std::string
& lock_name
);
351 virtual int try_lock(const DoutPrefixProvider
*dpp
, utime_t dur
, optional_yield y
) override
;
353 return lock
.unlock(&ioctx
, oid
);
357 class LCRadosSerializer
: public LCSerializer
{
358 librados::IoCtx
* ioctx
;
359 rados::cls::lock::Lock lock
;
360 const std::string oid
;
363 LCRadosSerializer(RGWRadosStore
* store
, const std::string
& oid
, const std::string
& lock_name
, const std::string
& cookie
);
365 virtual int try_lock(const DoutPrefixProvider
*dpp
, utime_t dur
, optional_yield y
) override
;
367 return lock
.unlock(ioctx
, oid
);
371 class RadosLifecycle
: public Lifecycle
{
372 RGWRadosStore
* store
;
375 RadosLifecycle(RGWRadosStore
* _st
) : store(_st
) {}
377 virtual int get_entry(const string
& oid
, const std::string
& marker
, LCEntry
& entry
) override
;
378 virtual int get_next_entry(const string
& oid
, std::string
& marker
, LCEntry
& entry
) override
;
379 virtual int set_entry(const string
& oid
, const LCEntry
& entry
) override
;
380 virtual int list_entries(const string
& oid
, const string
& marker
,
381 uint32_t max_entries
, vector
<LCEntry
>& entries
) override
;
382 virtual int rm_entry(const string
& oid
, const LCEntry
& entry
) override
;
383 virtual int get_head(const string
& oid
, LCHead
& head
) override
;
384 virtual int put_head(const string
& oid
, const LCHead
& head
) override
;
385 virtual LCSerializer
* get_serializer(const std::string
& lock_name
, const std::string
& oid
, const std::string
& cookie
) override
;
388 } } // namespace rgw::sal
390 class RGWStoreManager
{
393 static rgw::sal::RGWRadosStore
*get_storage(const DoutPrefixProvider
*dpp
, CephContext
*cct
, bool use_gc_thread
, bool use_lc_thread
, bool quota_threads
,
394 bool run_sync_thread
, bool run_reshard_thread
, bool use_cache
= true) {
395 rgw::sal::RGWRadosStore
*store
= init_storage_provider(dpp
, cct
, use_gc_thread
, use_lc_thread
,
396 quota_threads
, run_sync_thread
, run_reshard_thread
, use_cache
);
399 static rgw::sal::RGWRadosStore
*get_raw_storage(const DoutPrefixProvider
*dpp
, CephContext
*cct
) {
400 rgw::sal::RGWRadosStore
*rados
= init_raw_storage_provider(dpp
, cct
);
403 static rgw::sal::RGWRadosStore
*init_storage_provider(const DoutPrefixProvider
*dpp
, CephContext
*cct
, bool use_gc_thread
, bool use_lc_thread
, bool quota_threads
, bool run_sync_thread
, bool run_reshard_thread
, bool use_metadata_cache
);
404 static rgw::sal::RGWRadosStore
*init_raw_storage_provider(const DoutPrefixProvider
*dpp
, CephContext
*cct
);
405 static void close_storage(rgw::sal::RGWRadosStore
*store
);