From: Yehuda Sadeh Date: Thu, 21 Feb 2013 00:22:40 +0000 (-0800) Subject: rgw: can list regions, show default region info X-Git-Tag: v0.67-rc1~128^2~206 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=5cc34ff0c55544c6277017ea875254203fc341b9;p=ceph.git rgw: can list regions, show default region info Signed-off-by: Yehuda Sadeh --- diff --git a/src/rgw/rgw_admin.cc b/src/rgw/rgw_admin.cc index 4070c19fb10a..f33956dc6042 100644 --- a/src/rgw/rgw_admin.cc +++ b/src/rgw/rgw_admin.cc @@ -62,6 +62,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"; @@ -167,6 +168,7 @@ enum { OPT_GC_LIST, OPT_GC_PROCESS, OPT_REGION_INFO, + OPT_REGION_LIST, OPT_ZONE_INFO, OPT_ZONE_SET, OPT_CAPS_ADD, @@ -280,6 +282,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; @@ -633,7 +637,7 @@ int main(int argc, char **argv) RGWStreamFlusher f(formatter, cout); - bool raw_storage_op = (opt_cmd == OPT_REGION_INFO); + bool raw_storage_op = (opt_cmd == OPT_REGION_INFO || opt_cmd == OPT_REGION_LIST); if (raw_storage_op) { @@ -654,12 +658,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 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 c0a23d4dd8bb..97db750ebe89 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& regions) +{ + string pool_name = RGWRegion::get_pool_name(cct); + + rgw_bucket pool(pool_name.c_str()); + bool is_truncated; + RGWListRawObjsCtx ctx; + do { + vector oids; + int r = list_raw_objects(pool, region_info_oid_prefix, 1000, + ctx, oids, &is_truncated); + if (r < 0) { + return r; + } + vector::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. @@ -3664,6 +3678,44 @@ int RGWRados::pool_iterate(RGWPoolIterCtx& ctx, uint32_t num, vector& 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& 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 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::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 f0568013df5c..f31d8c73174e 100644 --- a/src/rgw/rgw_rados.h +++ b/src/rgw/rgw_rados.h @@ -239,6 +239,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; @@ -318,6 +325,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 endpoints; @@ -344,13 +370,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); }; @@ -512,6 +539,8 @@ public: } } + int list_regions(list& regions); + void tick(); CephContext *ctx() { return cct; } @@ -915,6 +944,10 @@ public: int pool_iterate(RGWPoolIterCtx& ctx, uint32_t num, vector& objs, bool *is_truncated, RGWAccessListFilter *filter); + int list_raw_objects(rgw_bucket& pool, const string& prefix_filter, int max, + RGWListRawObjsCtx& ctx, vector& oids, + bool *is_truncated); + uint64_t instance_id(); uint64_t next_bucket_id();