]>
git.proxmox.com Git - ceph.git/blob - ceph/src/rgw/rgw_bucket.cc
1 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2 // vim: ts=8 sw=2 smarttab ft=cpp
4 #include "rgw_bucket.h"
6 #include "common/errno.h"
8 #define dout_subsys ceph_subsys_rgw
10 // stolen from src/cls/version/cls_version.cc
11 #define VERSION_ATTR "ceph.objclass.version"
15 static void set_err_msg(std::string
*sink
, std::string msg
)
17 if (sink
&& !msg
.empty())
21 void init_bucket(rgw_bucket
*b
, const char *t
, const char *n
, const char *dp
, const char *ip
, const char *m
, const char *id
)
27 b
->explicit_placement
.data_pool
= rgw_pool(dp
);
28 b
->explicit_placement
.index_pool
= rgw_pool(ip
);
31 // parse key in format: [tenant/]name:instance[:shard_id]
32 int rgw_bucket_parse_bucket_key(CephContext
*cct
, const string
& key
,
33 rgw_bucket
*bucket
, int *shard_id
)
35 std::string_view name
{key
};
36 std::string_view instance
;
39 auto pos
= name
.find('/');
40 if (pos
!= string::npos
) {
41 auto tenant
= name
.substr(0, pos
);
42 bucket
->tenant
.assign(tenant
.begin(), tenant
.end());
43 name
= name
.substr(pos
+ 1);
45 bucket
->tenant
.clear();
48 // split name:instance
50 if (pos
!= string::npos
) {
51 instance
= name
.substr(pos
+ 1);
52 name
= name
.substr(0, pos
);
54 bucket
->name
.assign(name
.begin(), name
.end());
56 // split instance:shard
57 pos
= instance
.find(':');
58 if (pos
== string::npos
) {
59 bucket
->bucket_id
.assign(instance
.begin(), instance
.end());
67 auto shard
= instance
.substr(pos
+ 1);
69 auto id
= strict_strtol(shard
.data(), 10, &err
);
72 ldout(cct
, 0) << "ERROR: failed to parse bucket shard '"
73 << instance
.data() << "': " << err
<< dendl
;
81 instance
= instance
.substr(0, pos
);
82 bucket
->bucket_id
.assign(instance
.begin(), instance
.end());
87 * Note that this is not a reversal of parse_bucket(). That one deals
88 * with the syntax we need in metadata and such. This one deals with
89 * the representation in RADOS pools. We chose '/' because it's not
90 * acceptable in bucket names and thus qualified buckets cannot conflict
91 * with the legacy or S3 buckets.
93 std::string
rgw_make_bucket_entry_name(const std::string
& tenant_name
,
94 const std::string
& bucket_name
) {
95 std::string bucket_entry
;
97 if (bucket_name
.empty()) {
99 } else if (tenant_name
.empty()) {
100 bucket_entry
= bucket_name
;
102 bucket_entry
= tenant_name
+ "/" + bucket_name
;
109 * Tenants are separated from buckets in URLs by a colon in S3.
110 * This function is not to be used on Swift URLs, not even for COPY arguments.
112 int rgw_parse_url_bucket(const string
&bucket
, const string
& auth_tenant
,
113 string
&tenant_name
, string
&bucket_name
) {
115 int pos
= bucket
.find(':');
118 * N.B.: We allow ":bucket" syntax with explicit empty tenant in order
119 * to refer to the legacy tenant, in case users in new named tenants
120 * want to access old global buckets.
122 tenant_name
= bucket
.substr(0, pos
);
123 bucket_name
= bucket
.substr(pos
+ 1);
124 if (bucket_name
.empty()) {
125 return -ERR_INVALID_BUCKET_NAME
;
128 tenant_name
= auth_tenant
;
129 bucket_name
= bucket
;
134 int rgw_chown_bucket_and_objects(rgw::sal::Driver
* driver
, rgw::sal::Bucket
* bucket
,
135 rgw::sal::User
* new_user
,
136 const std::string
& marker
, std::string
*err_msg
,
137 const DoutPrefixProvider
*dpp
, optional_yield y
)
139 /* Chown on the bucket */
140 int ret
= bucket
->chown(dpp
, *new_user
, y
);
142 set_err_msg(err_msg
, "Failed to change object ownership: " + cpp_strerror(-ret
));
145 /* Now chown on all the objects in the bucket */
146 map
<string
, bool> common_prefixes
;
148 rgw::sal::Bucket::ListParams params
;
149 rgw::sal::Bucket::ListResults results
;
151 params
.list_versions
= true;
152 params
.allow_unordered
= true;
153 params
.marker
= marker
;
156 int max_entries
= 1000;
158 //Loop through objects and update object acls to point to bucket owner
161 results
.objs
.clear();
162 ret
= bucket
->list(dpp
, params
, max_entries
, results
, y
);
164 ldpp_dout(dpp
, 0) << "ERROR: list objects failed: " << cpp_strerror(-ret
) << dendl
;
168 params
.marker
= results
.next_marker
;
169 count
+= results
.objs
.size();
171 for (const auto& obj
: results
.objs
) {
172 std::unique_ptr
<rgw::sal::Object
> r_obj
= bucket
->get_object(obj
.key
);
174 ret
= r_obj
->chown(*new_user
, dpp
, y
);
176 ldpp_dout(dpp
, 0) << "ERROR: chown failed on " << r_obj
<< " :" << cpp_strerror(-ret
) << dendl
;
180 cerr
<< count
<< " objects processed in " << bucket
181 << ". Next marker " << params
.marker
.name
<< std::endl
;
182 } while(results
.is_truncated
);