]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
radosgw-admin: bucket stats --sync-stats [--bucket=...]
authorYehuda Sadeh <yehuda@inktank.com>
Wed, 8 Jan 2014 22:15:15 +0000 (14:15 -0800)
committerYehuda Sadeh <yehuda@inktank.com>
Fri, 24 Jan 2014 18:28:48 +0000 (10:28 -0800)
Sync user stats, either for a single buckets, or for all user's buckets.

Signed-off-by: Yehuda Sadeh <yehuda@inktank.com>
src/rgw/rgw_admin.cc
src/rgw/rgw_bucket.cc
src/rgw/rgw_bucket.h
src/rgw/rgw_rados.cc
src/rgw/rgw_rados.h

index ac92e57cd01b3795f8044a41c3a3aa03702e5ad6..faf0fd139b61107c1219e28a837e3d5ac6aa27c8 100644 (file)
@@ -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<const char*> 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<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);
index d805ec09d6452ed3198e1b36e91ba2e3bbbd4c0a..0b9f4dc356e250dff861cbdd7d3e4e948405cf01 100644 (file)
@@ -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;
index 607c53d40c12ed484a5f212279c07de0398e2069..d0aed9553422eb7f03e6b31ef37c4f94dccb10fd 100644 (file)
@@ -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<string, bufferlist> *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.
index 35fdf6dbb54fcba77625ee225d29c0a5d9bf9db6..391c3a85f26920f20fecf2a2c1d8a6a63efe66b4 100644 (file)
@@ -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<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,
index ff5936536f038c5662ba7c157872b479b58e3595..14e898eab1b0102a25cdaaa237aea819873d0c37 100644 (file)
@@ -1411,6 +1411,7 @@ public:
   int remove_objs_from_index(rgw_bucket& bucket, list<string>& 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<cls_user_bucket_entry>& entries,