From: Yehuda Sadeh Date: Wed, 8 Jan 2014 22:15:15 +0000 (-0800) Subject: radosgw-admin: bucket stats --sync-stats [--bucket=...] X-Git-Tag: v0.78~270^2~29 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=cbe1da85c85cfd7ff733a43b14d4748fd45b50c7;p=ceph.git radosgw-admin: bucket stats --sync-stats [--bucket=...] Sync user stats, either for a single buckets, or for all user's buckets. Signed-off-by: Yehuda Sadeh --- diff --git a/src/rgw/rgw_admin.cc b/src/rgw/rgw_admin.cc index ac92e57cd01b..faf0fd139b61 100644 --- a/src/rgw/rgw_admin.cc +++ b/src/rgw/rgw_admin.cc @@ -187,7 +187,7 @@ enum { OPT_USER_SUSPEND, OPT_USER_ENABLE, OPT_USER_CHECK, - OPT_USER_STAT, + OPT_USER_STATS, OPT_SUBUSER_CREATE, OPT_SUBUSER_MODIFY, OPT_SUBUSER_RM, @@ -301,8 +301,8 @@ static int get_cmd(const char *cmd, const char *prev_cmd, bool *need_more) 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; @@ -723,6 +723,24 @@ int set_user_bucket_quota(int opt_cmd, RGWUser& user, RGWUserAdminOpState& op_st 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 args; @@ -790,6 +808,8 @@ int main(int argc, char **argv) bool have_max_objects = false; bool have_max_size = false; + int sync_stats = false; + std::string val; std::ostringstream errs; string err; @@ -919,6 +939,8 @@ int main(int argc, char **argv) // 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)) { @@ -1888,12 +1910,52 @@ next: 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& buckets = user_buckets.get_buckets(); + for (map::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); diff --git a/src/rgw/rgw_bucket.cc b/src/rgw/rgw_bucket.cc index d805ec09d645..0b9f4dc356e2 100644 --- a/src/rgw/rgw_bucket.cc +++ b/src/rgw/rgw_bucket.cc @@ -29,7 +29,7 @@ static RGWMetadataHandler *bucket_meta_handler = NULL; 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; @@ -78,6 +78,15 @@ int rgw_read_user_buckets(RGWRados *store, string user_id, RGWUserBuckets& bucke 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; diff --git a/src/rgw/rgw_bucket.h b/src/rgw/rgw_bucket.h index 607c53d40c12..d0aed9553422 100644 --- a/src/rgw/rgw_bucket.h +++ b/src/rgw/rgw_bucket.h @@ -20,7 +20,7 @@ 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 *pattrs, RGWObjVersionTracker *objv_tracker, @@ -33,6 +33,7 @@ extern int rgw_bucket_instance_remove_entry(RGWRados *store, string& entry, RGWO 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. diff --git a/src/rgw/rgw_rados.cc b/src/rgw/rgw_rados.cc index 35fdf6dbb54f..391c3a85f269 100644 --- a/src/rgw/rgw_rados.cc +++ b/src/rgw/rgw_rados.cc @@ -5607,6 +5607,39 @@ int RGWRados::cls_user_get_header(rgw_obj& obj, cls_user_header *header) 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::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 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& entries, diff --git a/src/rgw/rgw_rados.h b/src/rgw/rgw_rados.h index ff5936536f03..14e898eab1b0 100644 --- a/src/rgw/rgw_rados.h +++ b/src/rgw/rgw_rados.h @@ -1411,6 +1411,7 @@ public: int remove_objs_from_index(rgw_bucket& bucket, list& oid_list); int cls_user_get_header(rgw_obj& obj, cls_user_header *header); + int cls_user_sync_bucket_stats(rgw_obj& user_obj, rgw_bucket& bucket); int cls_user_list_buckets(rgw_obj& obj, const string& in_marker, int max_entries, list& entries,