summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYehuda Sadeh <yehuda@inktank.com>2013-02-22 12:42:18 -0800
committerYehuda Sadeh <yehuda@inktank.com>2013-02-25 15:01:20 -0800
commit6f5cac427f8814be012ada6f70666fdcad929d30 (patch)
tree39dcb1ca16ba3cf2ade27b64b706ddee36e27346
parent8b626203e300d4d4b3d0b4b296e491895025fd62 (diff)
downloadceph-6f5cac427f8814be012ada6f70666fdcad929d30.tar.gz
rgw: regionmap update
Signed-off-by: Yehuda Sadeh <yehuda@inktank.com>
-rw-r--r--src/common/ceph_json.cc11
-rw-r--r--src/common/ceph_json.h1
-rw-r--r--src/rgw/rgw_admin.cc45
-rw-r--r--src/rgw/rgw_json_enc.cc4
-rw-r--r--src/rgw/rgw_rados.cc70
-rw-r--r--src/rgw/rgw_rados.h28
6 files changed, 145 insertions, 14 deletions
diff --git a/src/common/ceph_json.cc b/src/common/ceph_json.cc
index dd8eca2df4b..f88f1bd8255 100644
--- a/src/common/ceph_json.cc
+++ b/src/common/ceph_json.cc
@@ -375,6 +375,17 @@ void encode_json(const char *name, const char *val, Formatter *f)
f->dump_string(name, val);
}
+void encode_json(const char *name, bool val, Formatter *f)
+{
+ string s;
+ if (val)
+ s = "true";
+ else
+ s = "false";
+
+ f->dump_string(name, s);
+}
+
void encode_json(const char *name, int val, Formatter *f)
{
f->dump_int(name, val);
diff --git a/src/common/ceph_json.h b/src/common/ceph_json.h
index 324aa9f52c0..066e69e6b89 100644
--- a/src/common/ceph_json.h
+++ b/src/common/ceph_json.h
@@ -234,6 +234,7 @@ class utime_t;
void encode_json(const char *name, const string& val, Formatter *f);
void encode_json(const char *name, const char *val, Formatter *f);
+void encode_json(const char *name, bool val, Formatter *f);
void encode_json(const char *name, int val, Formatter *f);
void encode_json(const char *name, unsigned val, Formatter *f);
void encode_json(const char *name, long val, Formatter *f);
diff --git a/src/rgw/rgw_admin.cc b/src/rgw/rgw_admin.cc
index 941fb28ce67..9c1fa16d74b 100644
--- a/src/rgw/rgw_admin.cc
+++ b/src/rgw/rgw_admin.cc
@@ -178,6 +178,7 @@ enum {
OPT_REGION_DEFAULT,
OPT_REGIONMAP_SHOW,
OPT_REGIONMAP_SET,
+ OPT_REGIONMAP_UPDATE,
OPT_ZONE_INFO,
OPT_ZONE_SET,
OPT_ZONE_LIST,
@@ -328,6 +329,8 @@ static int get_cmd(const char *cmd, const char *prev_cmd, bool *need_more)
return OPT_REGIONMAP_SHOW;
if (strcmp(cmd, "set") == 0)
return OPT_REGIONMAP_SET;
+ if (strcmp(cmd, "update") == 0)
+ return OPT_REGIONMAP_UPDATE;
} else if (strcmp(prev_cmd, "zone") == 0) {
if (strcmp(cmd, "info") == 0)
return OPT_ZONE_INFO;
@@ -1021,6 +1024,7 @@ int main(int argc, char **argv)
bool raw_storage_op = (opt_cmd == OPT_REGION_INFO || opt_cmd == OPT_REGION_LIST ||
opt_cmd == OPT_REGION_SET || opt_cmd == OPT_REGION_DEFAULT ||
opt_cmd == OPT_REGIONMAP_SHOW || opt_cmd == OPT_REGIONMAP_SET ||
+ opt_cmd == OPT_REGIONMAP_UPDATE ||
opt_cmd == OPT_ZONE_INFO || opt_cmd == OPT_ZONE_SET ||
opt_cmd == OPT_ZONE_LIST);
@@ -1145,6 +1149,47 @@ int main(int argc, char **argv)
formatter->flush(cout);
}
+ if (opt_cmd == OPT_REGIONMAP_UPDATE) {
+ RGWRegionMap regionmap;
+ int ret = regionmap.read(g_ceph_context, store);
+ if (ret < 0 && ret != -ENOENT) {
+ cerr << "failed to read region map: " << cpp_strerror(-ret) << std::endl;
+ return -ret;
+ }
+
+ RGWRegion region;
+ ret = region.init(g_ceph_context, store, false);
+ if (ret < 0) {
+ cerr << "failed to init region: " << cpp_strerror(-ret) << std::endl;
+ return -ret;
+ }
+
+ list<string> regions;
+ ret = store->list_regions(regions);
+ if (ret < 0) {
+ cerr << "failed to list regions: " << cpp_strerror(-ret) << std::endl;
+ return -ret;
+ }
+
+ for (list<string>::iterator iter = regions.begin(); iter != regions.end(); ++iter) {
+ ret = region.read_info(*iter);
+ if (ret < 0) {
+ cerr << "failed to read region info (name=" << *iter << "): " << cpp_strerror(-ret) << std::endl;
+ return -ret;
+ }
+ regionmap.update(region);
+ }
+
+ ret = regionmap.store(g_ceph_context, store);
+ if (ret < 0) {
+ cerr << "ERROR: couldn't store region map info: " << cpp_strerror(-ret) << std::endl;
+ return 1;
+ }
+
+ encode_json("region-map", regionmap, formatter);
+ formatter->flush(cout);
+ }
+
if (opt_cmd == OPT_ZONE_INFO) {
RGWRegion region;
int ret = region.init(g_ceph_context, store);
diff --git a/src/rgw/rgw_json_enc.cc b/src/rgw/rgw_json_enc.cc
index c9874a05170..aa16da1e39a 100644
--- a/src/rgw/rgw_json_enc.cc
+++ b/src/rgw/rgw_json_enc.cc
@@ -465,6 +465,8 @@ void RGWZone::decode_json(JSONObj *obj)
void RGWRegion::dump(Formatter *f) const
{
encode_json("name", name, f);
+ encode_json("api_name", api_name, f);
+ encode_json("is_master", is_master, f);
encode_json("endpoints", endpoints, f);
encode_json("master_zone", master_zone, f);
encode_json("zones", zones, f);
@@ -481,6 +483,8 @@ static void decode_zones(map<string, RGWZone>& zones, JSONObj *o)
void RGWRegion::decode_json(JSONObj *obj)
{
JSONDecoder::decode_json("name", name, obj);
+ JSONDecoder::decode_json("api_name", api_name, obj);
+ JSONDecoder::decode_json("is_master", is_master, obj);
JSONDecoder::decode_json("endpoints", endpoints, obj);
JSONDecoder::decode_json("master_zone", master_zone, obj);
JSONDecoder::decode_json("zones", zones, decode_zones, obj);
diff --git a/src/rgw/rgw_rados.cc b/src/rgw/rgw_rados.cc
index f94c9c06ee0..52b91cd56bd 100644
--- a/src/rgw/rgw_rados.cc
+++ b/src/rgw/rgw_rados.cc
@@ -143,9 +143,7 @@ int RGWRegion::init(CephContext *_cct, RGWRados *_store, bool setup_region)
if (!setup_region)
return 0;
- string pool_name = get_pool_name(cct);
-
- name = cct->_conf->rgw_region;
+ string region_name = cct->_conf->rgw_region;
if (name.empty()) {
RGWDefaultRegionInfo default_info;
@@ -161,12 +159,20 @@ int RGWRegion::init(CephContext *_cct, RGWRados *_store, bool setup_region)
lderr(cct) << "failed reading default region info: " << cpp_strerror(-r) << dendl;
return r;
}
- name = default_info.default_region;
+ string region_name = default_info.default_region;
}
+ return read_info(name);
+}
+
+int RGWRegion::read_info(const string& region_name)
+{
+ string pool_name = get_pool_name(cct);
rgw_bucket pool(pool_name.c_str());
bufferlist bl;
+ name = region_name;
+
string oid = region_info_oid_prefix + name;
int ret = rgw_get_obj(store, NULL, pool, oid, bl);
@@ -306,6 +312,30 @@ int RGWZoneParams::store_info(CephContext *cct, RGWRados *store, RGWRegion& regi
return ret;
}
+void RGWRegionMap::encode(bufferlist& bl) const {
+ ENCODE_START(1, 1, bl);
+ ::encode(regions, bl);
+ ::encode(master_region, bl);
+ ENCODE_FINISH(bl);
+}
+
+void RGWRegionMap::decode(bufferlist::iterator& bl) {
+ DECODE_START(1, bl);
+ ::decode(regions, bl);
+ ::decode(master_region, bl);
+ DECODE_FINISH(bl);
+
+ regions_by_api.clear();
+ for (map<string, RGWRegion>::iterator iter = regions.begin();
+ iter != regions.end(); ++iter) {
+ RGWRegion& region = iter->second;
+ regions_by_api[region.api_name] = region;
+ if (region.is_master) {
+ master_region = region.name;
+ }
+ }
+}
+
void RGWRegionMap::get_params(CephContext *cct, string& pool_name, string& oid)
{
pool_name = cct->_conf->rgw_zone_root_pool;
@@ -328,6 +358,8 @@ int RGWRegionMap::read(CephContext *cct, RGWRados *store)
if (ret < 0)
return ret;
+
+ Mutex::Locker l(lock);
try {
bufferlist::iterator iter = bl.begin();
::decode(*this, iter);
@@ -347,6 +379,8 @@ int RGWRegionMap::store(CephContext *cct, RGWRados *store)
rgw_bucket pool(pool_name.c_str());
+ Mutex::Locker l(lock);
+
bufferlist bl;
::encode(*this, bl);
int ret = rgw_put_system_obj(store, pool, oid, bl.c_str(), bl.length(), false, NULL);
@@ -354,6 +388,34 @@ int RGWRegionMap::store(CephContext *cct, RGWRados *store)
return ret;
}
+int RGWRegionMap::update(RGWRegion& region)
+{
+ Mutex::Locker l(lock);
+
+ if (region.is_master && !master_region.empty() &&
+ master_region.compare(region.name) != 0) {
+ derr << "cannot update region map, master_region conflict" << dendl;
+ return -EINVAL;
+ }
+ map<string, RGWRegion>::iterator iter = regions.find(region.name);
+ if (iter != regions.end()) {
+ RGWRegion& old_region = iter->second;
+ if (!old_region.api_name.empty()) {
+ regions_by_api.erase(old_region.api_name);
+ }
+ }
+ regions[region.name] = region;
+
+ if (!region.api_name.empty()) {
+ regions_by_api[region.api_name] = region;
+ }
+
+ if (region.is_master) {
+ master_region = region.name;
+ }
+ return 0;
+}
+
void RGWObjManifest::append(RGWObjManifest& m)
{
map<uint64_t, RGWObjManifestPart>::iterator iter;
diff --git a/src/rgw/rgw_rados.h b/src/rgw/rgw_rados.h
index 5c65cc4e476..f87a6eed2ea 100644
--- a/src/rgw/rgw_rados.h
+++ b/src/rgw/rgw_rados.h
@@ -348,7 +348,9 @@ WRITE_CLASS_ENCODER(RGWDefaultRegionInfo);
struct RGWRegion {
string name;
+ string api_name;
list<string> endpoints;
+ bool is_master;
string master_zone;
map<string, RGWZone> zones;
@@ -356,8 +358,13 @@ struct RGWRegion {
CephContext *cct;
RGWRados *store;
+ RGWRegion() : is_master(false) {}
+
void encode(bufferlist& bl) const {
ENCODE_START(1, 1, bl);
+ ::encode(name, bl);
+ ::encode(api_name, bl);
+ ::encode(is_master, bl);
::encode(endpoints, bl);
::encode(master_zone, bl);
::encode(zones, bl);
@@ -366,6 +373,9 @@ struct RGWRegion {
void decode(bufferlist::iterator& bl) {
DECODE_START(1, bl);
+ ::decode(name, bl);
+ ::decode(api_name, bl);
+ ::decode(is_master, bl);
::decode(endpoints, bl);
::decode(master_zone, bl);
::decode(zones, bl);
@@ -375,6 +385,7 @@ struct RGWRegion {
int init(CephContext *_cct, RGWRados *_store, bool setup_region = true);
int create_default();
int store_info(bool exclusive);
+ int read_info(const string& region_name);
int read_default(RGWDefaultRegionInfo& default_region);
int set_as_default();
@@ -386,26 +397,23 @@ struct RGWRegion {
WRITE_CLASS_ENCODER(RGWRegion);
struct RGWRegionMap {
+ Mutex lock;
map<string, RGWRegion> regions;
+ map<string, RGWRegion> regions_by_api;
string master_region;
- void encode(bufferlist& bl) const {
- ENCODE_START(1, 1, bl);
- ::encode(regions, bl);
- ENCODE_FINISH(bl);
- }
+ RGWRegionMap() : lock("RGWRegionMap") {}
- void decode(bufferlist::iterator& bl) {
- DECODE_START(1, bl);
- ::decode(regions, bl);
- DECODE_FINISH(bl);
- }
+ void encode(bufferlist& bl) const;
+ void decode(bufferlist::iterator& bl);
void get_params(CephContext *cct, string& pool_name, string& oid);
int read(CephContext *cct, RGWRados *store);
int store(CephContext *cct, RGWRados *store);
+ int update(RGWRegion& region);
+
void dump(Formatter *f) const;
void decode_json(JSONObj *obj);
};