From e65afc56136c1c5e8517fdede80216b868303616 Mon Sep 17 00:00:00 2001 From: Orit Wasserman Date: Wed, 14 Oct 2015 12:53:50 +0200 Subject: [PATCH] rgw: add zonegroup modify command to allow setting/clearing zonegroup master status Signed-off-by: Orit Wasserman --- src/rgw/rgw_admin.cc | 76 ++++++++++++++++++++++++++++++++++++++++---- src/rgw/rgw_rados.cc | 34 ++++++++------------ src/rgw/rgw_rados.h | 6 ++-- 3 files changed, 87 insertions(+), 29 deletions(-) diff --git a/src/rgw/rgw_admin.cc b/src/rgw/rgw_admin.cc index 6eafb9e711f3a..86924ea1eac33 100644 --- a/src/rgw/rgw_admin.cc +++ b/src/rgw/rgw_admin.cc @@ -97,6 +97,7 @@ void _usage() cerr << " zonegroup default set default zone group\n"; cerr << " zonegroup delete delete a zone group info\n"; cerr << " zonegroup get show zone group info\n"; + cerr << " zonegroup modify set/clear zonegroup master status\n"; cerr << " zonegroup set set zone group info (requires infile)\n"; cerr << " zonegroup rename rename a zone group\n"; cerr << " zonegroup list list all zone groups set on this cluster\n"; @@ -178,7 +179,7 @@ void _usage() cerr << " --parent= parent period id\n"; cerr << " --period= period id\n"; cerr << " --epoch= period epoch\n"; - cerr << " --master= set as master\n"; + cerr << " --master set as master\n"; cerr << " --master-url master url\n"; cerr << " --master-zonegroup= master zonegroup id\n"; cerr << " --master-zone= master zone id\n"; @@ -295,6 +296,7 @@ enum { OPT_ZONEGROUP_DEFAULT, OPT_ZONEGROUP_DELETE, OPT_ZONEGROUP_GET, + OPT_ZONEGROUP_MODIFY, OPT_ZONEGROUP_SET, OPT_ZONEGROUP_LIST, OPT_ZONEGROUP_RENAME , @@ -558,6 +560,8 @@ static int get_cmd(const char *cmd, const char *prev_cmd, const char *prev_prev_ return OPT_ZONEGROUP_DELETE; if (strcmp(cmd, "get") == 0) return OPT_ZONEGROUP_GET; + if (strcmp(cmd, "modify") == 0) + return OPT_ZONEGROUP_MODIFY; if (strcmp(cmd, "list") == 0) return OPT_ZONEGROUP_LIST; if (strcmp(cmd, "set") == 0) @@ -1350,7 +1354,7 @@ int main(int argc, char **argv) std::string zone_name, zone_id, zone_new_name; std::string zonegroup_name, zonegroup_id, zonegroup_new_name; std::string master_url; - bool is_master = false; + int is_master = false; int key_type = KEY_TYPE_UNDEFINED; rgw_bucket bucket; uint32_t perm_mask = 0; @@ -1649,8 +1653,7 @@ int main(int argc, char **argv) } } else if (ceph_argparse_witharg(args, i, &val, "--parent", (char*)NULL)) { parent_period = val; - } else if (ceph_argparse_witharg(args, i, &val, "--master", (char*)NULL)) { - is_master = true; + } else if (ceph_argparse_binary_flag(args, i, &is_master, NULL, "--master", (char*)NULL)) { } else if (ceph_argparse_witharg(args, i, &val, "--master-url", (char*)NULL)) { master_url = val; } else if (ceph_argparse_witharg(args, i, &val, "--master-zonegroup", (char*)NULL)) { @@ -1773,9 +1776,9 @@ int main(int argc, char **argv) RGWStreamFlusher f(formatter, cout); bool raw_storage_op = (opt_cmd == OPT_ZONEGROUP_CREATE || opt_cmd == OPT_ZONEGROUP_DELETE || - opt_cmd == OPT_ZONEGROUP_GET || opt_cmd == OPT_ZONEGROUP_LIST || + opt_cmd == OPT_ZONEGROUP_GET || opt_cmd == OPT_ZONEGROUP_LIST || opt_cmd == OPT_ZONEGROUP_SET || opt_cmd == OPT_ZONEGROUP_DEFAULT || - opt_cmd == OPT_ZONEGROUP_RENAME || + opt_cmd == OPT_ZONEGROUP_RENAME || opt_cmd == OPT_ZONEGROUP_MODIFY || opt_cmd == OPT_ZONEGROUPMAP_GET || opt_cmd == OPT_ZONEGROUPMAP_SET || opt_cmd == OPT_ZONEGROUPMAP_UPDATE || opt_cmd == OPT_ZONE_ADD || opt_cmd == OPT_ZONE_CREATE || opt_cmd == OPT_ZONE_DELETE || @@ -2331,6 +2334,67 @@ int main(int argc, char **argv) cout << std::endl; } break; + case OPT_ZONEGROUP_MODIFY: + { + RGWRealm realm(realm_id, realm_name); + int ret = realm.init(g_ceph_context, store); + if (ret < 0) { + cerr << "failed to init realm: " << cpp_strerror(-ret) << std::endl; + return -ret; + } + + RGWZoneGroup zonegroup(zonegroup_id, zonegroup_name); + ret = zonegroup.init(g_ceph_context, store); + if (ret < 0) { + cerr << "failed to init zonegroup: " << cpp_strerror(-ret) << std::endl; + return -ret; + } + + /* update zonegroup only if there is a change */ + if (is_master != zonegroup.is_master_zonegroup()) { + zonegroup.update_master(is_master); + ret = zonegroup.update(); + if (ret < 0) { + cerr << "failed to update zonegroup: " << cpp_strerror(-ret) << std::endl; + return -ret; + } + } + + RGWZoneGroupMap zonegroup_map; + ret = zonegroup_map.read(g_ceph_context, store); + if (ret < 0 && ret != -ENOENT) { + cerr << "ERROR: couldn't read zonegroup_map: " << cpp_strerror(-ret) << std::endl; + return ret; + } + + string master_zonegroup; + if (ret != -ENOENT) { + ret = zonegroup_map.get_master_zonegroup(realm.get_current_period(), master_zonegroup); + if (ret < 0 && ret != -ENOENT) { + cerr << "ERROR: couldn't read zonegroup_map: " << cpp_strerror(-ret) << std::endl; + return ret; + } + } + + if (is_master) { + /* zonegroup already set as master zonegroup nothing to do*/ + if (master_zonegroup == zonegroup.get_id()) { + return 0; + } + } + + ret = zonegroup_map.update(g_ceph_context, store, realm, zonegroup); + if (ret < 0) { + cerr << "failed to update master zonegroup: " << cpp_strerror(-ret) << std::endl; + return -ret; + } + ret = zonegroup_map.store(g_ceph_context, store); + if (ret < 0) { + cerr << "failed to store zonegroup_map: " << cpp_strerror(-ret) << std::endl; + return -ret; + } + } + break; case OPT_ZONEGROUP_SET: { RGWRealm realm(realm_id, realm_name); diff --git a/src/rgw/rgw_rados.cc b/src/rgw/rgw_rados.cc index 030aa0362e11a..fc93afbce356a 100644 --- a/src/rgw/rgw_rados.cc +++ b/src/rgw/rgw_rados.cc @@ -1039,11 +1039,11 @@ void RGWPeriodMap::decode(bufferlist::iterator& bl) { } } - int RGWPeriodMap::update(const RGWZoneGroup& zonegroup) { - if (zonegroup.is_master && !zonegroup.equals(master_zonegroup)) { - derr << "cannot update zonegroup map, master_zonegroup conflict" << dendl; + if (zonegroup.is_master && (!master_zonegroup.empty() && zonegroup.get_id() != master_zonegroup)) { + derr << "cannot update zonegroup map, master_zonegroup conflict master zonegroup " << + master_zonegroup << dendl; return -EINVAL; } map::iterator iter = zonegroups.find(zonegroup.get_id()); @@ -1061,7 +1061,10 @@ int RGWPeriodMap::update(const RGWZoneGroup& zonegroup) if (zonegroup.is_master) { master_zonegroup = zonegroup.get_id(); + } else if (master_zonegroup == zonegroup.get_id()) { + master_zonegroup = ""; } + return 0; } @@ -1244,7 +1247,7 @@ int RGWZoneGroupMap::update_master_zonegroup(const string& period_id, } int RGWZoneGroupMap::get_master_zonegroup(const string& current_period, - RGWZoneGroup& zonegroup) + string& master_zonegroup) { map::iterator period_iter = periods.find(current_period); if (period_iter == periods.end()) { @@ -1252,18 +1255,7 @@ int RGWZoneGroupMap::get_master_zonegroup(const string& current_period, return -EINVAL; } - string master_zonegroup = period_iter->second.master_zonegroup; - if (master_zonegroup.empty()) { - return -ENOENT; - } - - 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; - } - - zonegroup = iter->second; + master_zonegroup = period_iter->second.master_zonegroup; return 0; } @@ -2969,10 +2961,10 @@ int RGWRados::init_complete() } } } else { - RGWZoneGroup master_zonegroup; + string master_zonegroup; for (map::iterator iter = zonegroup_map.realms.begin(); iter != zonegroup_map.realms.end(); iter++) { - if (master_zonegroup.get_id().empty()) { + if (master_zonegroup.empty()) { ret = zonegroup_map.get_master_zonegroup(iter->second.get_current_period(), master_zonegroup); if (ret < 0 && ret != -ENOENT) { ldout(cct, 0) << "ERROR: failed to read master zonegroup:" << cpp_strerror(-ret) << dendl; @@ -2989,9 +2981,9 @@ int RGWRados::init_complete() for ( map::iterator iter = zonegroups.begin(); iter != zonegroups.end(); ++iter) { RGWZoneGroup& zonegroup = iter->second; add_new_connection_to_map(zonegroup_conn_map, zonegroup, new RGWRESTConn(cct, this, zonegroup.endpoints)); - } - if (!master_zonegroup.get_id().empty()) { - rest_master_conn = new RGWRESTConn(cct, this, master_zonegroup.endpoints); + if (!master_zonegroup.empty() && zonegroup.get_id() == master_zonegroup) { + rest_master_conn = new RGWRESTConn(cct, this, zonegroup.endpoints); + } } } } diff --git a/src/rgw/rgw_rados.h b/src/rgw/rgw_rados.h index b0f0b8779d060..03f524f6773d8 100644 --- a/src/rgw/rgw_rados.h +++ b/src/rgw/rgw_rados.h @@ -1077,6 +1077,9 @@ struct RGWZoneGroup : public RGWSystemMetaObj { const string& _realm_id) : RGWSystemMetaObj(_name, cct , store),is_master(_is_master), realm_id(_realm_id) {} + bool is_master_zonegroup() const { return is_master;} + void update_master(bool _is_master) { is_master = _is_master;} + void encode(bufferlist& bl) const { ENCODE_START(4, 1, bl); ::encode(name, bl); @@ -1204,9 +1207,8 @@ struct RGWZoneGroupMap { 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); + string& master_zonegroup); int get_zonegroups(const string& current_period, map& zonegroups); -- 2.39.5