diff options
author | Yehuda Sadeh <yehuda@inktank.com> | 2013-02-20 16:22:40 -0800 |
---|---|---|
committer | Yehuda Sadeh <yehuda@inktank.com> | 2013-03-22 11:23:58 -0700 |
commit | 1ad4db5ffeaa5ec0699462e2282fdd2f78724da3 (patch) | |
tree | 2cfad3e7764f21143b496ce5fc1825e79a821c96 | |
parent | 09860e236efdc01c804713aa8649571f5055d711 (diff) | |
download | ceph-1ad4db5ffeaa5ec0699462e2282fdd2f78724da3.tar.gz |
rgw: can list regions, show default region info
Signed-off-by: Yehuda Sadeh <yehuda@inktank.com>
-rw-r--r-- | src/rgw/rgw_admin.cc | 29 | ||||
-rw-r--r-- | src/rgw/rgw_rados.cc | 102 | ||||
-rw-r--r-- | src/rgw/rgw_rados.h | 39 |
3 files changed, 141 insertions, 29 deletions
diff --git a/src/rgw/rgw_admin.cc b/src/rgw/rgw_admin.cc index 804395106f7..e318c1440a6 100644 --- a/src/rgw/rgw_admin.cc +++ b/src/rgw/rgw_admin.cc @@ -61,6 +61,7 @@ void _usage() cerr << " object rm remove object\n"; cerr << " object unlink unlink object from bucket index\n"; cerr << " region info show region info\n"; + cerr << " region list list all regions\n"; cerr << " zone info show zone params info\n"; cerr << " pool add add an existing pool for data placement\n"; cerr << " pool rm remove an existing pool from data placement set\n"; @@ -166,6 +167,7 @@ enum { OPT_GC_LIST, OPT_GC_PROCESS, OPT_REGION_INFO, + OPT_REGION_LIST, OPT_ZONE_INFO, OPT_ZONE_SET, OPT_CAPS_ADD, @@ -297,6 +299,8 @@ static int get_cmd(const char *cmd, const char *prev_cmd, bool *need_more) } else if (strcmp(prev_cmd, "region") == 0) { if (strcmp(cmd, "info") == 0) return OPT_REGION_INFO; + if (strcmp(cmd, "list") == 0) + return OPT_REGION_LIST; } else if (strcmp(prev_cmd, "zone") == 0) { if (strcmp(cmd, "info") == 0) return OPT_ZONE_INFO; @@ -981,7 +985,7 @@ int main(int argc, char **argv) return usage(); } - bool raw_storage_op = (opt_cmd == OPT_REGION_INFO); + bool raw_storage_op = (opt_cmd == OPT_REGION_INFO || opt_cmd == OPT_REGION_LIST); user_modify_op = (opt_cmd == OPT_USER_MODIFY || opt_cmd == OPT_SUBUSER_MODIFY || @@ -1007,12 +1011,35 @@ int main(int argc, char **argv) int ret = region.init(g_ceph_context, store); if (ret < 0) { cerr << "failed to init region: " << cpp_strerror(-ret) << std::endl; + return -ret; } encode_json("region", region, formatter); formatter->flush(cout); cout << std::endl; } + if (opt_cmd == OPT_REGION_LIST) { + RGWRegion region; + int ret = region.init(g_ceph_context, store, false); + + list<string> regions; + ret = store->list_regions(regions); + if (ret < 0) { + cerr << "failed to list regions: " << cpp_strerror(-ret) << std::endl; + return -ret; + } + RGWDefaultRegionInfo default_region; + ret = region.read_default(default_region); + if (ret < 0 && ret != -ENOENT) { + cerr << "could not determine default region: " << cpp_strerror(-ret) << std::endl; + } + formatter->open_object_section("regions_list"); + encode_json("default_info", default_region, formatter); + encode_json("regions", regions, formatter); + formatter->close_section(); + formatter->flush(cout); + cout << std::endl; + } return 0; } diff --git a/src/rgw/rgw_rados.cc b/src/rgw/rgw_rados.cc index cc11e3b1be4..8a447cc4de0 100644 --- a/src/rgw/rgw_rados.cc +++ b/src/rgw/rgw_rados.cc @@ -65,28 +65,13 @@ static RGWObjCategory main_category = RGW_OBJ_CATEGORY_MAIN; #define dout_subsys ceph_subsys_rgw -struct RGWDefaultRegionInfo { - string default_region; - - void encode(bufferlist& bl) const { - ENCODE_START(1, 1, bl); - ::encode(default_region, bl); - ENCODE_FINISH(bl); - } +void RGWDefaultRegionInfo::dump(Formatter *f) const { + encode_json("default_region", default_region, f); +} - void decode(bufferlist::iterator& bl) { - DECODE_START(1, bl); - ::decode(default_region, bl); - DECODE_FINISH(bl); - } - void dump(Formatter *f) const { - encode_json("default_region", default_region, f); - } - void decode_json(JSONObj *obj) { - JSONDecoder::decode_json("default_region", default_region, obj); - } -}; -WRITE_CLASS_ENCODER(RGWDefaultRegionInfo); +void RGWDefaultRegionInfo::decode_json(JSONObj *obj) { + JSONDecoder::decode_json("default_region", default_region, obj); +} string RGWRegion::get_pool_name(CephContext *cct) { @@ -97,7 +82,7 @@ string RGWRegion::get_pool_name(CephContext *cct) return pool_name; } -int RGWRegion::read_default() +int RGWRegion::read_default(RGWDefaultRegionInfo& default_info) { string pool_name = get_pool_name(cct); @@ -112,7 +97,6 @@ int RGWRegion::read_default() if (ret < 0) return ret; - RGWDefaultRegionInfo default_info; try { bufferlist::iterator iter = bl.begin(); ::decode(default_info, iter); @@ -150,17 +134,21 @@ int RGWRegion::set_as_default() return 0; } -int RGWRegion::init(CephContext *_cct, RGWRados *_store) +int RGWRegion::init(CephContext *_cct, RGWRados *_store, bool setup_region) { cct = _cct; store = _store; + if (!setup_region) + return 0; + string pool_name = get_pool_name(cct); name = cct->_conf->rgw_region; if (name.empty()) { - int r = read_default(); + RGWDefaultRegionInfo default_info; + int r = read_default(default_info); if (r == -ENOENT) { r = create_default(); if (r < 0) @@ -172,6 +160,7 @@ int RGWRegion::init(CephContext *_cct, RGWRados *_store) lderr(cct) << "failed reading default region info: " << cpp_strerror(-r) << dendl; return r; } + name = default_info.default_region; } rgw_bucket pool(pool_name.c_str()); @@ -237,6 +226,8 @@ int RGWRegion::store_info(bool exclusive) return ret; } + + void RGWZoneParams::init_default() { domain_root = ".rgw"; @@ -453,6 +444,29 @@ void RGWRados::finalize_watch() delete[] watchers; } +int RGWRados::list_regions(list<string>& regions) +{ + string pool_name = RGWRegion::get_pool_name(cct); + + rgw_bucket pool(pool_name.c_str()); + bool is_truncated; + RGWListRawObjsCtx ctx; + do { + vector<string> oids; + int r = list_raw_objects(pool, region_info_oid_prefix, 1000, + ctx, oids, &is_truncated); + if (r < 0) { + return r; + } + vector<string>::iterator iter; + for (iter = oids.begin(); iter != oids.end(); ++iter) { + regions.push_back(iter->substr(region_info_oid_prefix.size() + 1)); + } + } while (is_truncated); + + return 0; +} + /** * Open the pool used as root for this gateway * Returns: 0 on success, -ERR# otherwise. @@ -3639,6 +3653,44 @@ int RGWRados::pool_iterate(RGWPoolIterCtx& ctx, uint32_t num, vector<RGWObjEnt>& return objs.size(); } +struct RGWAccessListFilterPrefix : public RGWAccessListFilter { + string prefix; + + RGWAccessListFilterPrefix(const string& _prefix) : prefix(_prefix) {} + virtual bool filter(string& name, string& key) { + return (prefix.compare(key.substr(0, prefix.size())) == 0); + } +}; + +int RGWRados::list_raw_objects(rgw_bucket& pool, const string& prefix_filter, + int max, RGWListRawObjsCtx& ctx, vector<string>& oids, + bool *is_truncated) +{ + RGWAccessListFilterPrefix filter(prefix_filter); + + if (!ctx.initialized) { + int r = pool_iterate_begin(pool, ctx.iter_ctx); + if (r < 0) { + lderr(cct) << "failed to list objects pool_iterate_begin() returned r=" << r << dendl; + return r; + } + ctx.initialized = true; + } + + vector<RGWObjEnt> objs; + int r = pool_iterate(ctx.iter_ctx, max, objs, is_truncated, &filter); + if (r < 0) { + lderr(cct) << "failed to list objects pool_iterate returned r=" << r << dendl; + return r; + } + + vector<RGWObjEnt>::iterator iter; + for (iter = objs.begin(); iter != objs.end(); ++iter) { + oids.push_back(iter->name); + } + + return oids.size(); +} int RGWRados::gc_operate(string& oid, librados::ObjectWriteOperation *op) { diff --git a/src/rgw/rgw_rados.h b/src/rgw/rgw_rados.h index f98473857b6..2368086cb48 100644 --- a/src/rgw/rgw_rados.h +++ b/src/rgw/rgw_rados.h @@ -238,6 +238,13 @@ struct RGWPoolIterCtx { librados::ObjectIterator iter; }; +struct RGWListRawObjsCtx { + bool initialized; + RGWPoolIterCtx iter_ctx; + + RGWListRawObjsCtx() : initialized(false) {} +}; + struct RGWZoneParams { rgw_bucket domain_root; rgw_bucket control_pool; @@ -317,6 +324,25 @@ struct RGWZone { }; WRITE_CLASS_ENCODER(RGWZone); +struct RGWDefaultRegionInfo { + string default_region; + + void encode(bufferlist& bl) const { + ENCODE_START(1, 1, bl); + ::encode(default_region, bl); + ENCODE_FINISH(bl); + } + + void decode(bufferlist::iterator& bl) { + DECODE_START(1, bl); + ::decode(default_region, bl); + DECODE_FINISH(bl); + } + void dump(Formatter *f) const; + void decode_json(JSONObj *obj); +}; +WRITE_CLASS_ENCODER(RGWDefaultRegionInfo); + struct RGWRegion { string name; list<string> endpoints; @@ -343,13 +369,14 @@ struct RGWRegion { DECODE_FINISH(bl); } - string get_pool_name(CephContext *cct); - int init(CephContext *_cct, RGWRados *_store); + int init(CephContext *_cct, RGWRados *_store, bool setup_region = true); int create_default(); int store_info(bool exclusive); - int read_default(); + int read_default(RGWDefaultRegionInfo& default_region); int set_as_default(); + static string get_pool_name(CephContext *cct); + void dump(Formatter *f) const; void decode_json(JSONObj *obj); }; @@ -511,6 +538,8 @@ public: } } + int list_regions(list<string>& regions); + void tick(); CephContext *ctx() { return cct; } @@ -906,6 +935,10 @@ public: int pool_iterate(RGWPoolIterCtx& ctx, uint32_t num, vector<RGWObjEnt>& objs, bool *is_truncated, RGWAccessListFilter *filter); + int list_raw_objects(rgw_bucket& pool, const string& prefix_filter, int max, + RGWListRawObjsCtx& ctx, vector<string>& oids, + bool *is_truncated); + uint64_t instance_id(); uint64_t next_bucket_id(); |