]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
rgw: regionmap update
authorYehuda Sadeh <yehuda@inktank.com>
Fri, 22 Feb 2013 20:42:18 +0000 (12:42 -0800)
committerYehuda Sadeh <yehuda@inktank.com>
Wed, 8 May 2013 17:54:54 +0000 (10:54 -0700)
Signed-off-by: Yehuda Sadeh <yehuda@inktank.com>
src/common/ceph_json.cc
src/common/ceph_json.h
src/rgw/rgw_admin.cc
src/rgw/rgw_json_enc.cc
src/rgw/rgw_rados.cc
src/rgw/rgw_rados.h

index 598cb819f0f1dfabf1b5b539f17de9f45a0899e9..4a6c1ea58e02a66c8b843c134bb12c5d545bc298 100644 (file)
@@ -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);
index ec049e5a2955cd97d202f25d9a4605c605bbff03..04ca4c1e4a12bebfdb95cd2dff21ad8304a3ad60 100644 (file)
@@ -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);
index e1dba681cb6ea3278e62cc880ae45ef489a76a9d..9756187e4e794b955fbc48a0715f765d940ad341 100644 (file)
@@ -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<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);
index 64377c6a3f171333eb3780fa95521c436a6cd38f..f299f0e64b0c2745b58522e561d51fd693319abf 100644 (file)
@@ -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<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);
index 4d4e63a8e7639532c7763042a462492574deeaf3..1de333e7f57a965cd8bc58d31f2e3afa245f52b6 100644 (file)
@@ -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;
index 078d826ede325271527af697e0045ed6f8c857d9..1f1ebe6848bda6b044b0e93d80880d5d67e3084a 100644 (file)
@@ -349,7 +349,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;
@@ -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<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);
 };