From: Yehuda Sadeh Date: Fri, 22 Feb 2013 20:42:18 +0000 (-0800) Subject: rgw: regionmap update X-Git-Tag: v0.67-rc1~128^2~201 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=8bb5e0a2efaec2e972daf89af1e6b2c70f737942;p=ceph.git rgw: regionmap update Signed-off-by: Yehuda Sadeh --- diff --git a/src/common/ceph_json.cc b/src/common/ceph_json.cc index 598cb819f0f..4a6c1ea58e0 100644 --- a/src/common/ceph_json.cc +++ b/src/common/ceph_json.cc @@ -432,6 +432,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 ec049e5a295..04ca4c1e4a1 100644 --- a/src/common/ceph_json.h +++ b/src/common/ceph_json.h @@ -236,6 +236,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 e1dba681cb6..9756187e4e7 100644 --- a/src/rgw/rgw_admin.cc +++ b/src/rgw/rgw_admin.cc @@ -179,6 +179,7 @@ enum { OPT_REGION_DEFAULT, OPT_REGIONMAP_SHOW, OPT_REGIONMAP_SET, + OPT_REGIONMAP_UPDATE, OPT_ZONE_INFO, OPT_ZONE_SET, OPT_ZONE_LIST, @@ -313,6 +314,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; @@ -674,6 +677,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); @@ -793,6 +797,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 regions; + ret = store->list_regions(regions); + if (ret < 0) { + cerr << "failed to list regions: " << cpp_strerror(-ret) << std::endl; + return -ret; + } + + for (list::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 64377c6a3f1..f299f0e64b0 100644 --- a/src/rgw/rgw_json_enc.cc +++ b/src/rgw/rgw_json_enc.cc @@ -475,6 +475,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); @@ -491,6 +493,8 @@ static void decode_zones(map& 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 4d4e63a8e76..1de333e7f57 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::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::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::iterator iter; diff --git a/src/rgw/rgw_rados.h b/src/rgw/rgw_rados.h index 078d826ede3..1f1ebe6848b 100644 --- a/src/rgw/rgw_rados.h +++ b/src/rgw/rgw_rados.h @@ -349,7 +349,9 @@ WRITE_CLASS_ENCODER(RGWDefaultRegionInfo); struct RGWRegion { string name; + string api_name; list endpoints; + bool is_master; string master_zone; map zones; @@ -357,8 +359,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); @@ -367,6 +374,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); @@ -376,6 +386,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(); @@ -387,26 +398,23 @@ struct RGWRegion { WRITE_CLASS_ENCODER(RGWRegion); struct RGWRegionMap { + Mutex lock; map regions; + map 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); };