OPT_USER_SUSPEND,
OPT_USER_ENABLE,
OPT_USER_CHECK,
- OPT_USER_STAT,
+ OPT_USER_STATS,
OPT_SUBUSER_CREATE,
OPT_SUBUSER_MODIFY,
OPT_SUBUSER_RM,
return OPT_USER_ENABLE;
if (strcmp(cmd, "check") == 0)
return OPT_USER_CHECK;
- if (strcmp(cmd, "stat") == 0)
- return OPT_USER_STAT;
+ if (strcmp(cmd, "stats") == 0)
+ return OPT_USER_STATS;
} else if (strcmp(prev_cmd, "subuser") == 0) {
if (strcmp(cmd, "create") == 0)
return OPT_SUBUSER_CREATE;
return 0;
}
+static int sync_bucket_stats(RGWRados *store, string& bucket_name)
+{
+ RGWBucketInfo bucket_info;
+ int r = store->get_bucket_info(NULL, bucket_name, bucket_info, NULL);
+ if (r < 0) {
+ cerr << "ERROR: could not fetch bucket info: " << cpp_strerror(-r) << std::endl;
+ return r;
+ }
+
+ r = rgw_bucket_sync_user_stats(store, bucket_info.owner, bucket_info.bucket);
+ if (r < 0) {
+ cerr << "ERROR: could not sync user stats for bucket " << bucket_name << ": " << cpp_strerror(-r) << std::endl;
+ return r;
+ }
+
+ return 0;
+}
+
int main(int argc, char **argv)
{
vector<const char*> args;
bool have_max_objects = false;
bool have_max_size = false;
+ int sync_stats = false;
+
std::string val;
std::ostringstream errs;
string err;
// do nothing
} else if (ceph_argparse_binary_flag(args, i, &check_objects, NULL, "--check-objects", (char*)NULL)) {
// do nothing
+ } else if (ceph_argparse_binary_flag(args, i, &sync_stats, NULL, "--sync-stats", (char*)NULL)) {
+ // do nothing
} else if (ceph_argparse_witharg(args, i, &val, "--caps", (char*)NULL)) {
caps = val;
} else if (ceph_argparse_witharg(args, i, &val, "-i", "--infile", (char*)NULL)) {
check_bad_user_bucket_mapping(store, user_id, fix);
}
- if (opt_cmd == OPT_USER_STAT) {
+ if (opt_cmd == OPT_USER_STATS) {
+ if (sync_stats) {
+ if (!bucket_name.empty()) {
+ int ret = sync_bucket_stats(store, bucket_name);
+ if (ret < 0) {
+ cerr << "ERROR: could not sync bucket stats: " << cpp_strerror(-ret) << std::endl;
+ return -ret;
+ }
+ } else {
+ size_t max_entries = g_conf->rgw_list_buckets_max_chunk;
+
+ bool done;
+
+ do {
+ RGWUserBuckets user_buckets;
+ int ret = rgw_read_user_buckets(store, user_id, user_buckets, marker, max_entries, false);
+ if (ret < 0) {
+ cerr << "failed to read user buckets: " << cpp_strerror(-ret) << std::endl;
+ return -ret;
+ }
+
+ map<string, RGWBucketEnt>& buckets = user_buckets.get_buckets();
+ for (map<string, RGWBucketEnt>::iterator i = buckets.begin();
+ i != buckets.end();
+ ++i) {
+ marker = i->first;
+
+ RGWBucketEnt& bucket_ent = i->second;
+ ret = sync_bucket_stats(store, bucket_ent.bucket.name);
+ if (ret < 0) {
+ cerr << "ERROR: could not sync bucket stats: " << cpp_strerror(-ret) << std::endl;
+ return -ret;
+ }
+ }
+ done = (buckets.size() < max_entries);
+ } while (!done);
+ }
+ }
+
if (user_id.empty()) {
cerr << "ERROR: uid not specified" << std::endl;
return EINVAL;
}
- rgw_obj obj(store->zone.user_uid_pool, user_id);
+ string buckets_obj_id;
+ rgw_get_buckets_obj(user_id, buckets_obj_id);
+ rgw_obj obj(store->zone.user_uid_pool, buckets_obj_id);
cls_user_header header;
int ret = store->cls_user_get_header(obj, &header);
static RGWMetadataHandler *bucket_instance_meta_handler = NULL;
// define as static when RGWBucket implementation compete
-void rgw_get_buckets_obj(string& user_id, string& buckets_obj_id)
+void rgw_get_buckets_obj(const string& user_id, string& buckets_obj_id)
{
buckets_obj_id = user_id;
buckets_obj_id += RGW_BUCKETS_OBJ_SUFFIX;
return 0;
}
+int rgw_bucket_sync_user_stats(RGWRados *store, const string& user_id, rgw_bucket& bucket)
+{
+ string buckets_obj_id;
+ rgw_get_buckets_obj(user_id, buckets_obj_id);
+ rgw_obj obj(store->zone.user_uid_pool, buckets_obj_id);
+
+ return store->cls_user_sync_bucket_stats(obj, bucket);
+}
+
int rgw_link_bucket(RGWRados *store, string user_id, rgw_bucket& bucket, time_t creation_time, bool update_entrypoint)
{
int ret;
using namespace std;
// define as static when RGWBucket implementation compete
-extern void rgw_get_buckets_obj(string& user_id, string& buckets_obj_id);
+extern void rgw_get_buckets_obj(const string& user_id, string& buckets_obj_id);
extern int rgw_bucket_store_info(RGWRados *store, const string& bucket_name, bufferlist& bl, bool exclusive,
map<string, bufferlist> *pattrs, RGWObjVersionTracker *objv_tracker,
extern int rgw_bucket_delete_bucket_obj(RGWRados *store, string& bucket_name, RGWObjVersionTracker& objv_tracker);
+extern int rgw_bucket_sync_user_stats(RGWRados *store, const string& user_id, rgw_bucket& bucket);
/**
* Store a list of the user's buckets, with associated functinos.
return 0;
}
+int RGWRados::cls_user_sync_bucket_stats(rgw_obj& user_obj, rgw_bucket& bucket)
+{
+ rgw_bucket_dir_header header;
+ int r = cls_bucket_head(bucket, header);
+ if (r < 0) {
+ ldout(cct, 20) << "cls_bucket_header() returned " << r << dendl;
+ return r;
+ }
+
+ cls_user_bucket_entry entry;
+
+ bucket.convert(&entry.bucket);
+
+ map<uint8_t, struct rgw_bucket_category_stats>::iterator iter = header.stats.begin();
+ for (; iter != header.stats.end(); ++iter) {
+ struct rgw_bucket_category_stats& header_stats = iter->second;
+ entry.size += header_stats.total_size;
+ entry.size_rounded += header_stats.total_size_rounded;
+ entry.count += header_stats.num_entries;
+ }
+
+ list<cls_user_bucket_entry> entries;
+ entries.push_back(entry);
+
+ r = cls_user_update_buckets(user_obj, entries);
+ if (r < 0) {
+ ldout(cct, 20) << "cls_user_update_buckets() returned " << r << dendl;
+ return r;
+ }
+
+ return 0;
+}
+
int RGWRados::cls_user_list_buckets(rgw_obj& obj,
const string& in_marker, int max_entries,
list<cls_user_bucket_entry>& entries,