From: Yehuda Sadeh Date: Wed, 8 Jan 2014 01:29:39 +0000 (-0800) Subject: rgw, radosgw-admin, cls/user: retrieve user stats X-Git-Tag: v0.78~270^2~31 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=eef7ba48df7573194b687f167cc04e5c1c349750;p=ceph.git rgw, radosgw-admin, cls/user: retrieve user stats add a new op to retrieve user header, new radosgw-admin command to stat user. Signed-off-by: Yehuda Sadeh --- diff --git a/src/cls/Makefile.am b/src/cls/Makefile.am index b88b5cc33621c..22bbb3f32d4f1 100644 --- a/src/cls/Makefile.am +++ b/src/cls/Makefile.am @@ -100,7 +100,7 @@ DENCODER_DEPS += libcls_rgw_client.la libcls_rbd_client_la_SOURCES = cls/rbd/cls_rbd_client.cc noinst_LTLIBRARIES += libcls_rbd_client.la -libcls_user_client_a_SOURCES = cls/user/cls_user_client.cc +libcls_user_client_a_SOURCES = cls/user/cls_user_client.cc cls/user/cls_user_types.cc noinst_LIBRARIES += libcls_user_client.a noinst_HEADERS += \ diff --git a/src/cls/user/cls_user_client.h b/src/cls/user/cls_user_client.h index 0f65875dbd7ab..661397c82b828 100644 --- a/src/cls/user/cls_user_client.h +++ b/src/cls/user/cls_user_client.h @@ -18,5 +18,6 @@ void cls_user_bucket_list(librados::ObjectReadOperation& op, const string& in_marker, int max_entries, list& entries, string *out_marker, bool *truncated); +void cls_user_get_header(librados::ObjectReadOperation& op, cls_user_header *header); #endif diff --git a/src/cls/user/cls_user_types.cc b/src/cls/user/cls_user_types.cc new file mode 100644 index 0000000000000..59f0bdcac7a12 --- /dev/null +++ b/src/cls/user/cls_user_types.cc @@ -0,0 +1,14 @@ +// -*- mode:C; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- +// vim: ts=8 sw=2 smarttab + +#include "cls/user/cls_user_types.h" +#include "common/Formatter.h" + + +void cls_user_header::dump(Formatter *f) const +{ + f->dump_int("total_entries", total_entries); + f->dump_int("total_bytes", total_bytes); + f->dump_int("total_bytes_rounded", total_bytes_rounded); +} + diff --git a/src/cls/user/cls_user_types.h b/src/cls/user/cls_user_types.h index 1eddc10aadfa5..dde508b0ab7a7 100644 --- a/src/cls/user/cls_user_types.h +++ b/src/cls/user/cls_user_types.h @@ -127,6 +127,8 @@ struct cls_user_header { ::decode(total_bytes_rounded, bl); DECODE_FINISH(bl); } + + void dump(Formatter *f) const; }; WRITE_CLASS_ENCODER(cls_user_header) diff --git a/src/rgw/rgw_admin.cc b/src/rgw/rgw_admin.cc index cb6c3022396f0..ac92e57cd01b3 100644 --- a/src/rgw/rgw_admin.cc +++ b/src/rgw/rgw_admin.cc @@ -187,6 +187,7 @@ enum { OPT_USER_SUSPEND, OPT_USER_ENABLE, OPT_USER_CHECK, + OPT_USER_STAT, OPT_SUBUSER_CREATE, OPT_SUBUSER_MODIFY, OPT_SUBUSER_RM, @@ -300,6 +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; } else if (strcmp(prev_cmd, "subuser") == 0) { if (strcmp(cmd, "create") == 0) return OPT_SUBUSER_CREATE; @@ -1885,6 +1888,24 @@ next: check_bad_user_bucket_mapping(store, user_id, fix); } + if (opt_cmd == OPT_USER_STAT) { + if (user_id.empty()) { + cerr << "ERROR: uid not specified" << std::endl; + return EINVAL; + } + rgw_obj obj(store->zone.user_uid_pool, user_id); + + cls_user_header header; + int ret = store->cls_user_get_header(obj, &header); + if (ret < 0) { + cerr << "ERROR: can't read user header: " << cpp_strerror(-ret) << std::endl; + return -ret; + } + + encode_json("header", header, formatter); + formatter->flush(cout); + } + if (opt_cmd == OPT_METADATA_GET) { int ret = store->meta_mgr->get(metadata_key, formatter); if (ret < 0) { @@ -2333,5 +2354,6 @@ next: set_user_bucket_quota(opt_cmd, user, user_op, max_size, max_objects, have_max_size, have_max_objects); } } + return 0; } diff --git a/src/rgw/rgw_rados.cc b/src/rgw/rgw_rados.cc index 3d517f2add7e1..35fdf6dbb54fc 100644 --- a/src/rgw/rgw_rados.cc +++ b/src/rgw/rgw_rados.cc @@ -5587,12 +5587,31 @@ int RGWRados::cls_bucket_head_async(rgw_bucket& bucket, RGWGetDirHeader_CB *ctx) return 0; } +int RGWRados::cls_user_get_header(rgw_obj& obj, cls_user_header *header) +{ + librados::IoCtx io_ctx; + rgw_bucket bucket; + std::string oid, key; + get_obj_bucket_and_oid_key(obj, bucket, oid, key); + int r = open_bucket_data_ctx(bucket, io_ctx); + if (r < 0) + return r; + + librados::ObjectReadOperation op; + ::cls_user_get_header(op, header); + bufferlist ibl; + r = io_ctx.operate(oid, &op, &ibl); + if (r < 0) + return r; + + return 0; +} + int RGWRados::cls_user_list_buckets(rgw_obj& obj, const string& in_marker, int max_entries, list& entries, string *out_marker, bool *truncated) { - bufferlist bl; librados::IoCtx io_ctx; rgw_bucket bucket; std::string oid, key; diff --git a/src/rgw/rgw_rados.h b/src/rgw/rgw_rados.h index 22e459308f1c2..ff5936536f038 100644 --- a/src/rgw/rgw_rados.h +++ b/src/rgw/rgw_rados.h @@ -1410,6 +1410,7 @@ public: int bucket_rebuild_index(rgw_bucket& bucket); 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_list_buckets(rgw_obj& obj, const string& in_marker, int max_entries, list& entries,