diff options
author | Yehuda Sadeh <yehuda@inktank.com> | 2013-02-22 12:42:18 -0800 |
---|---|---|
committer | Yehuda Sadeh <yehuda@inktank.com> | 2013-03-22 11:23:58 -0700 |
commit | 469b0f5b002426ff27b2d171c5744b191f057eba (patch) | |
tree | 07d0214d328f925ad92ea07688589a96860acc9a | |
parent | d02df048809f09b5dffbf60cfce10ed6e52e1654 (diff) | |
download | ceph-469b0f5b002426ff27b2d171c5744b191f057eba.tar.gz |
rgw: regionmap update
Signed-off-by: Yehuda Sadeh <yehuda@inktank.com>
-rw-r--r-- | src/common/ceph_json.cc | 11 | ||||
-rw-r--r-- | src/common/ceph_json.h | 1 | ||||
-rw-r--r-- | src/rgw/rgw_admin.cc | 45 | ||||
-rw-r--r-- | src/rgw/rgw_json_enc.cc | 4 | ||||
-rw-r--r-- | src/rgw/rgw_rados.cc | 70 | ||||
-rw-r--r-- | src/rgw/rgw_rados.h | 28 |
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 2cde74fd9e2..e2c713dd39e 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, @@ -330,6 +331,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; @@ -1022,6 +1025,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); @@ -1146,6 +1150,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 9e1f51bd022..7225bbdf819 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 b2d953af0df..07ce69907c3 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); }; |