From 220e8e8609d87a31a968c75d30bf4241075f56f7 Mon Sep 17 00:00:00 2001 From: Orit Wasserman Date: Wed, 23 Sep 2015 20:33:50 +0200 Subject: [PATCH] rgw: add backward support for old regionmap format Signed-off-by: Orit Wasserman --- src/rgw/rgw_admin.cc | 61 +++++++++++++++++++++++++++++++++++++++-- src/rgw/rgw_json_enc.cc | 27 ++++++++++++------ src/rgw/rgw_rados.cc | 25 +++++++++++++++-- src/rgw/rgw_rados.h | 12 ++++---- 4 files changed, 107 insertions(+), 18 deletions(-) diff --git a/src/rgw/rgw_admin.cc b/src/rgw/rgw_admin.cc index 53d68c5298ee3..474d4ebb8c597 100644 --- a/src/rgw/rgw_admin.cc +++ b/src/rgw/rgw_admin.cc @@ -2407,9 +2407,66 @@ int main(int argc, char **argv) case OPT_ZONEGROUPMAP_SET: { RGWZoneGroupMap zonegroupmap; - int ret = read_decode_json(infile, zonegroupmap); + bufferlist bl; + int ret = read_input(infile, bl); if (ret < 0) { - return 1; + cerr << "ERROR: failed to read input: " << cpp_strerror(-ret) << std::endl; + return ret; + } + JSONParser p; + ret = p.parse(bl.c_str(), bl.length()); + if (ret < 0) { + cout << "failed to parse JSON" << std::endl; + return ret; + } + try { + decode_json_obj(zonegroupmap, &p); + } catch (JSONDecoder::err& e) { + cout << "failed to decode: " << e.message << std::endl; + RGWRegionMap region_map; + try { + decode_json_obj(region_map, &p); + RGWRealm realm(realm_id, realm_name); + ret = realm.init(g_ceph_context, store); + if (ret < 0) { + cerr << "failed to init realm: " << cpp_strerror(-ret) << std::endl; + return -ret; + } + + ret = zonegroupmap.update(realm); + if (ret < 0) { + cerr << "failed to update zonegroup_map: " << cpp_strerror(-ret) << std::endl; + } + + ret = zonegroupmap.update(g_ceph_context, store, realm.get_current_period(), realm.get_id()); + if (ret < 0) { + cerr << "ERROR: couldn't update current period: " << cpp_strerror(-ret) + << std::endl; + return ret; + } + + for(map::iterator iter = region_map.regions.begin(); + iter != region_map.regions.end(); iter++) { + iter->second.set_id(iter->second.get_name()); + ret = zonegroupmap.update(g_ceph_context, store, realm, iter->second); + if (ret < 0) { + cerr << "failed to update zonegroup_map: " << cpp_strerror(-ret) << std::endl; + return -ret; + } + } + ret = zonegroupmap.update_master_zonegroup(realm.get_current_period(), + region_map.master_region); + if (ret < 0) { + cerr << "ERROR: couldn't update master_zonegroup " << region_map.master_region << ": " + << cpp_strerror(-ret) << std::endl; + return ret; + } + zonegroupmap.bucket_quota = region_map.bucket_quota; + zonegroupmap.user_quota = region_map.user_quota; + } catch (JSONDecoder::err& e) { + cout << "failed to decode: " << e.message << std::endl; + return -EINVAL; + } } ret = zonegroupmap.store(g_ceph_context, store); diff --git a/src/rgw/rgw_json_enc.cc b/src/rgw/rgw_json_enc.cc index 52d57aa1ccd1a..b71022e462d26 100644 --- a/src/rgw/rgw_json_enc.cc +++ b/src/rgw/rgw_json_enc.cc @@ -892,6 +892,11 @@ static void decode_placement_targets(map& t void RGWZoneGroup::decode_json(JSONObj *obj) { RGWSystemMetaObj::decode_json(obj); + if (!id.empty()) { + derr << "old format " << dendl; + JSONDecoder::decode_json("name", name, obj); + id = name; + } JSONDecoder::decode_json("api_name", api_name, obj); JSONDecoder::decode_json("is_master", is_master, obj); JSONDecoder::decode_json("endpoints", endpoints, obj); @@ -912,10 +917,17 @@ void RGWPeriodMap::dump(Formatter *f) const encode_json("master_zonegroup", master_zonegroup, f); } +static void decode_zonegroups(map& zonegroups, JSONObj *o) +{ + RGWZoneGroup zg; + zg.decode_json(o); + zonegroups[zg.get_id()] = zg; +} + void RGWPeriodMap::decode_json(JSONObj *obj) { JSONDecoder::decode_json("id", id, obj); - JSONDecoder::decode_json("zonegroups", zonegroups, obj); + JSONDecoder::decode_json("zonegroups", zonegroups, decode_zonegroups, obj); /* backward compatability with region */ if (zonegroups.empty()) { JSONDecoder::decode_json("regions", zonegroups, obj); @@ -951,8 +963,11 @@ void RGWZoneGroupMap::dump(Formatter *f) const void RGWZoneGroupMap::decode_json(JSONObj *obj) { - JSONDecoder::decode_json("realms", realms, decode_realms, obj); - JSONDecoder::decode_json("periods", periods, decode_periods, obj); + /* check for old format */ + if (!JSONDecoder::decode_json("realms", realms, decode_realms, obj) ) { + throw JSONDecoder::err("Old regionmap format"); + } + JSONDecoder::decode_json("periods", periods, decode_periods, obj); JSONDecoder::decode_json("bucket_quota", bucket_quota, obj); JSONDecoder::decode_json("user_quota", user_quota, obj); } @@ -1005,12 +1020,6 @@ void RGWRealm::dump(Formatter *f) const encode_json("current_period", current_period, f); } -static void decode_zonegroups(map& zonegroups, JSONObj *o) -{ - RGWZoneGroup zg; - zg.decode_json(o); - zonegroups[zg.get_id()] = zg; -} void RGWRealm::decode_json(JSONObj *obj) { diff --git a/src/rgw/rgw_rados.cc b/src/rgw/rgw_rados.cc index 58646ee577a0f..3c376357f68bc 100644 --- a/src/rgw/rgw_rados.cc +++ b/src/rgw/rgw_rados.cc @@ -1088,7 +1088,7 @@ void RGWRegionMap::decode(bufferlist::iterator& bl) { } void RGWZoneGroupMap::encode(bufferlist& bl) const { - ENCODE_START(4, 1, bl); + ENCODE_START(1, 1, bl); ::encode(realms, bl); ::encode(periods, bl); ::encode(bucket_quota, bl); @@ -1097,7 +1097,7 @@ void RGWZoneGroupMap::encode(bufferlist& bl) const { } void RGWZoneGroupMap::decode(bufferlist::iterator& bl) { - DECODE_START(4, bl); + DECODE_START(1, bl); ::decode(realms, bl); ::decode(periods, bl); ::decode(bucket_quota, bl); @@ -1213,6 +1213,27 @@ int RGWZoneGroupMap::update(CephContext *cct, RGWRados *store, return 0; } + +int RGWZoneGroupMap::update_master_zonegroup(const string& period_id, + const string& master_zonegroup) +{ + map::iterator period_iter = periods.find(period_id); + if (period_iter == periods.end()) { + derr << "ERROR: period " << period_id << " not found" << dendl; + return -EINVAL; + } + + map::iterator iter = period_iter->second.zonegroups.find(master_zonegroup); + if (iter == period_iter->second.zonegroups.end()) { + derr << "ERROR: bad zonegroup map: inconsistent master zonegroup" << dendl; + return -EINVAL; + } + + period_iter->second.master_zonegroup = master_zonegroup; + + return 0; +} + int RGWZoneGroupMap::get_master_zonegroup(const string& current_period, RGWZoneGroup& zonegroup) { diff --git a/src/rgw/rgw_rados.h b/src/rgw/rgw_rados.h index ed851607dd397..656cca3b2047a 100644 --- a/src/rgw/rgw_rados.h +++ b/src/rgw/rgw_rados.h @@ -766,6 +766,9 @@ public: const string& get_name() const { return name; } const string& get_id() const { return id; } + void set_name(const string& _name) { name = _name;} + void set_id(const string& _id) { id = _id;} + virtual ~RGWSystemMetaObj() {} virtual void encode(bufferlist& bl) const { @@ -873,9 +876,6 @@ struct RGWZoneParams : RGWSystemMetaObj { void init_id(CephContext *cct, RGWZoneGroup& zonegroup); int create_default(bool old_format = false); - void set_name(const string& _name) { name = _name;} - void set_id(const string& _id) { id = _id;} - void encode(bufferlist& bl) const { ENCODE_START(6, 1, bl); ::encode(domain_root, bl); @@ -1202,8 +1202,10 @@ struct RGWZoneGroupMap { int update(RGWRealm& realm); int update(CephContext *cct, RGWRados *store, const string& period_id, - const string& realm_id); - + const string& realm_id); + int update_master_zonegroup(const string& period_id, + const string& master_zonegroup); + int get_master_zonegroup(const string& current_period, RGWZoneGroup& master_zonegroup); -- 2.39.5