#include "common/Formatter.h"
#include "common/ceph_json.h"
#include "common/RWLock.h"
+#include "common/backport14.h"
#include "rgw_rados.h"
#include "rgw_acl.h"
RGWBucketEnt& bucket_ent = i->second;
RGWBucketInfo bucket_info;
- ret = store->get_bucket_instance_info(obj_ctx, bucket_ent.bucket, bucket_info, NULL, NULL);
+ ret = store->get_bucket_info(obj_ctx, user_id.tenant, bucket_ent.bucket.name,
+ bucket_info, nullptr, nullptr);
if (ret < 0) {
ldout(cct, 0) << "ERROR: could not read bucket info: bucket=" << bucket_ent.bucket << " ret=" << ret << dendl;
continue;
return 0;
}
+int rgw_user_get_all_buckets_stats(RGWRados *store, const rgw_user& user_id, map<string, cls_user_bucket_entry>&buckets_usage_map)
+{
+ CephContext *cct = store->ctx();
+ size_t max_entries = cct->_conf->rgw_list_buckets_max_chunk;
+ bool done;
+ bool is_truncated;
+ string marker;
+ int ret;
+
+ do {
+ RGWUserBuckets user_buckets;
+ ret = rgw_read_user_buckets(store, user_id, user_buckets, marker,
+ string(), max_entries, false, &is_truncated);
+ if (ret < 0) {
+ ldout(cct, 0) << "failed to read user buckets: ret=" << ret << dendl;
+ return ret;
+ }
+ map<string, RGWBucketEnt>& buckets = user_buckets.get_buckets();
+ for (const auto& i : buckets) {
+ marker = i.first;
+
+ const RGWBucketEnt& bucket_ent = i.second;
+ cls_user_bucket_entry entry;
+ ret = store->cls_user_get_bucket_stats(bucket_ent.bucket, entry);
+ if (ret < 0) {
+ ldout(cct, 0) << "ERROR: could not get bucket stats: ret=" << ret << dendl;
+ return ret;
+ }
+ buckets_usage_map.emplace(bucket_ent.bucket.name, entry);
+ }
+ done = (buckets.size() < max_entries);
+ } while (!done);
+
+ return 0;
+}
+
/**
* Save the given user information to storage.
* Returns: 0 on success, -ERR# on failure.
return RGW_PERM_INVALID;
}
+int rgw_validate_tenant_name(const string& t)
+{
+ struct tench {
+ static bool is_good(char ch) {
+ return isalnum(ch) || ch == '_';
+ }
+ };
+ std::string::const_iterator it =
+ std::find_if_not(t.begin(), t.end(), tench::is_good);
+ return (it == t.end())? 0: -ERR_INVALID_TENANT_NAME;
+}
+
static bool validate_access_key(string& key)
{
const char *p = key.c_str();
{
bool found = false;
std::string swift_user;
- rgw_user& uid = op_state.get_user_id();
+ user_id = op_state.get_user_id();
std::string user_email = op_state.get_user_email();
std::string access_key = op_state.get_access_key();
std::string subuser = op_state.get_subuser();
clear_populated();
- if (uid.empty() && !subuser.empty()) {
+ if (user_id.empty() && !subuser.empty()) {
size_t pos = subuser.find(':');
if (pos != string::npos) {
- uid = subuser.substr(0, pos);
- op_state.set_user_id(uid);
+ user_id = subuser.substr(0, pos);
+ op_state.set_user_id(user_id);
}
}
- if (!uid.empty() && (uid.compare(RGW_USER_ANON_ID) != 0)) {
- found = (rgw_get_user_info_by_uid(store, uid, user_info, &op_state.objv) >= 0);
+ if (!user_id.empty() && (user_id.compare(RGW_USER_ANON_ID) != 0)) {
+ found = (rgw_get_user_info_by_uid(store, user_id, user_info, &op_state.objv) >= 0);
op_state.found_by_uid = found;
}
if (!user_email.empty() && !found) {
set_populated();
}
- user_id = user_info.user_id;
+ if (user_id.empty()) {
+ user_id = user_info.user_id;
+ }
op_state.set_initialized();
// this may have been called by a helper object
return -EINVAL;
}
+ int ret = rgw_validate_tenant_name(op_id.tenant);
+ if (ret) {
+ set_err_msg(err_msg,
+ "invalid tenant only alphanumeric and _ characters are allowed");
+ return ret;
+ }
+
//set key type when it not set or set by context
if ((op_state.get_key_type() < 0) || op_state.key_type_setbycontext) {
op_state.set_key_type(KEY_TYPE_S3);
if (ret < 0)
return ret;
+ if (op_state.sync_stats) {
+ ret = rgw_user_sync_all_stats(store, info.user_id);
+ if (ret < 0) {
+ return ret;
+ }
+ }
+
RGWStorageStats stats;
RGWStorageStats *arg_stats = NULL;
if (op_state.fetch_stats) {
int ret = store->get_user_stats(info.user_id, stats);
- if (ret < 0) {
+ if (ret < 0 && ret != -ENOENT) {
return ret;
}
pool = store->get_zone_params().user_uid_pool;
}
- int list_keys_init(RGWRados *store, void **phandle) override
+ int list_keys_init(RGWRados *store, const string& marker, void **phandle) override
{
- list_keys_info *info = new list_keys_info;
+ auto info = ceph::make_unique<list_keys_info>();
info->store = store;
- *phandle = (void *)info;
+ int ret = store->list_raw_objects_init(store->get_zone_params().user_uid_pool, marker,
+ &info->ctx);
+ if (ret < 0) {
+ return ret;
+ }
+
+ *phandle = (void *)info.release();
return 0;
}
list<string> unfiltered_keys;
- int ret = store->list_raw_objects(store->get_zone_params().user_uid_pool, no_filter,
- max, info->ctx, unfiltered_keys, truncated);
+ int ret = store->list_raw_objects_next(no_filter, max, info->ctx,
+ unfiltered_keys, truncated);
if (ret < 0 && ret != -ENOENT)
return ret;
if (ret == -ENOENT) {
list_keys_info *info = static_cast<list_keys_info *>(handle);
delete info;
}
+
+ string get_marker(void *handle) {
+ list_keys_info *info = static_cast<list_keys_info *>(handle);
+ return info->store->list_raw_objs_get_cursor(info->ctx);
+ }
};
void rgw_user_init(RGWRados *store)