summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYehuda Sadeh <yehuda@inktank.com>2013-02-20 16:22:40 -0800
committerYehuda Sadeh <yehuda@inktank.com>2013-02-25 15:00:06 -0800
commitca98a02aa6b93e98fe72fd62793f4d034b5eb1e9 (patch)
tree5f9df891697ace8ffc94cac91101eb861c6f0c2c
parent3351b631bd851b9479a0274993ead9158c8df659 (diff)
downloadceph-ca98a02aa6b93e98fe72fd62793f4d034b5eb1e9.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.cc29
-rw-r--r--src/rgw/rgw_rados.cc102
-rw-r--r--src/rgw/rgw_rados.h39
3 files changed, 141 insertions, 29 deletions
diff --git a/src/rgw/rgw_admin.cc b/src/rgw/rgw_admin.cc
index 36407d5566a..78c6d3c693c 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,
@@ -295,6 +297,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;
@@ -980,7 +984,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 ||
@@ -1006,12 +1010,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 504f1364151..18bb18ddf3a 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.
@@ -3622,6 +3636,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 36d32e19ee0..8168e6e540b 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();