do {
list<rgw_bi_log_entry> entries;
- ret = store->list_bi_log_entries(bucket, marker, max_entries - count, entries, &truncated);
+ ret = store->list_bi_log_entries(bucket, shard_id, marker, max_entries - count, entries, &truncated);
if (ret < 0) {
cerr << "ERROR: list_bi_log_entries(): " << cpp_strerror(-ret) << std::endl;
return -ret;
cerr << "ERROR: could not init bucket: " << cpp_strerror(-ret) << std::endl;
return -ret;
}
- ret = store->trim_bi_log_entries(bucket, start_marker, end_marker);
+ ret = store->trim_bi_log_entries(bucket, shard_id, start_marker, end_marker);
if (ret < 0) {
cerr << "ERROR: trim_bi_log_entries(): " << cpp_strerror(-ret) << std::endl;
return -ret;
return store->meta_mgr->remove_entry(bucket_instance_meta_handler, entry, objv_tracker);
}
+int rgw_bucket_parse_bucket_instance(const string& bucket_instance, string *target_bucket_instance, int *shard_id)
+{
+ ssize_t pos = bucket_instance.rfind(':');
+ if (pos < 0) {
+ return -EINVAL;
+ }
+
+ string first = bucket_instance.substr(0, pos);
+ string second = bucket_instance.substr(pos + 1);
+
+ if (first.find(':') == string::npos) {
+ *shard_id = -1;
+ *target_bucket_instance = bucket_instance;
+ return 0;
+ }
+
+ *target_bucket_instance = first;
+ string err;
+ *shard_id = strict_strtol(second.c_str(), 10, &err);
+ if (!err.empty()) {
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
int rgw_bucket_set_attrs(RGWRados *store, RGWBucketInfo& bucket_info,
map<string, bufferlist>& attrs,
map<string, bufferlist>* rmattrs,
map<string, bufferlist> *pattrs, RGWObjVersionTracker *objv_tracker,
time_t mtime);
+extern int rgw_bucket_parse_bucket_instance(const string& bucket_instance, string *target_bucket_instance, int *shard_id);
+
extern int rgw_bucket_instance_remove_entry(RGWRados *store, string& entry, RGWObjVersionTracker *objv_tracker);
extern int rgw_bucket_delete_bucket_obj(RGWRados *store, string& bucket_name, RGWObjVersionTracker& objv_tracker);
}
int RGWRados::open_bucket_index(rgw_bucket& bucket, librados::IoCtx& index_ctx,
- vector<string>& bucket_objs) {
+ vector<string>& bucket_objs, int shard_id) {
string bucket_oid_base;
int ret = open_bucket_index_base(bucket, index_ctx, bucket_oid_base);
if (ret < 0)
if (ret < 0)
return ret;
- get_bucket_index_objects(bucket_oid_base, binfo.num_shards, bucket_objs);
+ get_bucket_index_objects(bucket_oid_base, binfo.num_shards, bucket_objs, shard_id);
return 0;
}
template<typename T>
int RGWRados::open_bucket_index(rgw_bucket& bucket, librados::IoCtx& index_ctx,
- map<string, T>& bucket_objs)
+ map<string, T>& bucket_objs, int shard_id)
{
vector<string> oids;
- int ret = open_bucket_index(bucket, index_ctx, oids);
+ int ret = open_bucket_index(bucket, index_ctx, oids, shard_id);
if (ret < 0)
return ret;
return oids.size();
}
-int RGWRados::list_bi_log_entries(rgw_bucket& bucket, string& marker, uint32_t max,
+int RGWRados::list_bi_log_entries(rgw_bucket& bucket, int shard_id, string& marker, uint32_t max,
std::list<rgw_bi_log_entry>& result, bool *truncated)
{
ldout(cct, 20) << __func__ << bucket << " marker " << marker << " max " << max << dendl;
librados::IoCtx index_ctx;
map<string, cls_rgw_bi_log_list_ret> bi_log_lists;
- int r = open_bucket_index(bucket, index_ctx, bi_log_lists);
+ int r = open_bucket_index(bucket, index_ctx, bi_log_lists, shard_id);
if (r < 0)
return r;
BucketIndexShardsManager marker_mgr;
- bool has_shards = (bi_log_lists.size() > 1);
+ bool has_shards = (bi_log_lists.size() > 1 || shard_id >= 0);
// If there are multiple shards for the bucket index object, the marker
// should have the pattern '{shard_oid_1}#{shard_marker_1},{shard_oid_2}#
// {shard_marker_2}...', if there is no sharding, the bi_log_list should
return 0;
}
-int RGWRados::trim_bi_log_entries(rgw_bucket& bucket, string& start_marker, string& end_marker)
+int RGWRados::trim_bi_log_entries(rgw_bucket& bucket, int shard_id, string& start_marker, string& end_marker)
{
librados::IoCtx index_ctx;
vector<string> bucket_objs;
- int r = open_bucket_index(bucket, index_ctx, bucket_objs);
+ int r = open_bucket_index(bucket, index_ctx, bucket_objs, shard_id);
if (r < 0)
return r;
- bool has_shards = bucket_objs.size() > 1;
+ bool has_shards = bucket_objs.size() > 1 || shard_id >= 0;
BucketIndexShardsManager start_marker_mgr;
r = start_marker_mgr.from_string(start_marker, has_shards, bucket_objs.front());
if (r < 0)
}
void RGWRados::get_bucket_index_objects(const string& bucket_oid_base,
- const uint32_t num_shards, vector<string>& bucket_objects)
+ uint32_t num_shards, vector<string>& bucket_objects, int shard_id)
{
if (!num_shards) {
bucket_objects.push_back(bucket_oid_base);
} else {
char buf[bucket_oid_base.size() + 32];
- for (uint32_t i = 0; i < num_shards; ++i) {
- snprintf(buf, sizeof(buf), "%s.%d", bucket_oid_base.c_str(), i);
+ if (shard_id < 0) {
+ for (uint32_t i = 0; i < num_shards; ++i) {
+ snprintf(buf, sizeof(buf), "%s.%d", bucket_oid_base.c_str(), i);
+ bucket_objects.push_back(string(buf));
+ }
+ } else {
+ if ((uint32_t)shard_id > num_shards) {
+ return;
+ }
+ snprintf(buf, sizeof(buf), "%s.%d", bucket_oid_base.c_str(), shard_id);
bucket_objects.push_back(string(buf));
}
}
int open_bucket_index_shard(rgw_bucket& bucket, librados::IoCtx& index_ctx,
const string& obj_key, string *bucket_obj);
int open_bucket_index(rgw_bucket& bucket, librados::IoCtx& index_ctx,
- vector<string>& bucket_objs);
+ vector<string>& bucket_objs, int shard_id = -1);
template<typename T>
int open_bucket_index(rgw_bucket& bucket, librados::IoCtx& index_ctx,
- map<string, T>& bucket_objs);
+ map<string, T>& bucket_objs, int shard_id = -1);
void build_bucket_index_marker(const string& shard_name, const string& shard_marker,
string *marker);
return cls_obj_complete_cancel(bucket, tag, oid.object, oid.get_hash_object());
}
- int list_bi_log_entries(rgw_bucket& bucket, string& marker, uint32_t max, std::list<rgw_bi_log_entry>& result, bool *truncated);
- int trim_bi_log_entries(rgw_bucket& bucket, string& marker, string& end_marker);
+ int list_bi_log_entries(rgw_bucket& bucket, int shard_id, string& marker, uint32_t max, std::list<rgw_bi_log_entry>& result, bool *truncated);
+ int trim_bi_log_entries(rgw_bucket& bucket, int shard_id, string& marker, string& end_marker);
int cls_obj_usage_log_add(const string& oid, rgw_usage_log_info& info);
int cls_obj_usage_log_read(string& oid, string& user, uint64_t start_epoch, uint64_t end_epoch, uint32_t max_entries,
* num_shards [in] - number of bucket index object shards.
* bucket_objs [out] - filled by this method, a list of bucket index objects.
*/
- void get_bucket_index_objects(const string& bucket_oid_base, const uint32_t num_shards,
- vector<string>& bucket_objs);
+ void get_bucket_index_objects(const string& bucket_oid_base, uint32_t num_shards,
+ vector<string>& bucket_objs, int shard_id = -1);
/**
* Get the bucket index object with the given base bucket index object and object key,
return;
}
+ int shard_id;
+ http_ret = rgw_bucket_parse_bucket_instance(bucket_instance, &bucket_instance, &shard_id);
+ if (http_ret < 0) {
+ return;
+ }
+
if (!bucket_instance.empty()) {
http_ret = store->get_bucket_instance_info(NULL, bucket_instance, bucket_info, NULL, NULL);
if (http_ret < 0) {
send_response();
do {
list<rgw_bi_log_entry> entries;
- int ret = store->list_bi_log_entries(bucket_info.bucket,
+ int ret = store->list_bi_log_entries(bucket_info.bucket, shard_id,
marker, max_entries - count,
entries, &truncated);
if (ret < 0) {
http_ret = -EINVAL;
return;
}
+
+ int shard_id;
+ http_ret = rgw_bucket_parse_bucket_instance(bucket_instance, &bucket_instance, &shard_id);
+ if (http_ret < 0) {
+ return;
+ }
+
if (!bucket_instance.empty()) {
http_ret = store->get_bucket_instance_info(NULL, bucket_instance, bucket_info, NULL, NULL);
if (http_ret < 0) {
return;
}
}
- http_ret = store->trim_bi_log_entries(bucket_info.bucket, start_marker, end_marker);
+ http_ret = store->trim_bi_log_entries(bucket_info.bucket, shard_id, start_marker, end_marker);
if (http_ret < 0) {
dout(5) << "ERROR: trim_bi_log_entries() " << dendl;
}