]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
rgw: more storage class data structure changes
authorYehuda Sadeh <yehuda@redhat.com>
Fri, 22 Jun 2018 02:25:15 +0000 (19:25 -0700)
committerYehuda Sadeh <yehuda@redhat.com>
Fri, 4 Jan 2019 02:01:37 +0000 (18:01 -0800)
storage class also handles compression info

Signed-off-by: Yehuda Sadeh <yehuda@redhat.com>
src/common/ceph_json.h
src/rgw/rgw_admin.cc
src/rgw/rgw_json_enc.cc
src/rgw/rgw_op.cc
src/rgw/rgw_rados.cc
src/rgw/rgw_zone.cc
src/rgw/rgw_zone.h
src/rgw/services/svc_zone.cc

index 02b70758be5b1d50af92a3974c66ec412ca8b1b0..ba841d269daee805d5a12b578dca324fc5c34066 100644 (file)
@@ -142,6 +142,10 @@ public:
 
   template<class T>
   static void decode_json(const char *name, T& val, const T& default_val, JSONObj *obj);
+
+  template<class T>
+  static bool decode_json(const char *name, boost::optional<T>& val, JSONObj *obj, bool mandatory = false);
+
 };
 
 template<class T>
@@ -346,6 +350,32 @@ void JSONDecoder::decode_json(const char *name, T& val, const T& default_val, JS
   }
 }
 
+template<class T>
+bool JSONDecoder::decode_json(const char *name, boost::optional<T>& val, JSONObj *obj, bool mandatory)
+{
+  JSONObjIter iter = obj->find_first(name);
+  if (iter.end()) {
+    if (mandatory) {
+      string s = "missing mandatory field " + string(name);
+      throw err(s);
+    }
+    val = boost::none;
+    return false;
+  }
+
+  try {
+    val.reset(T());
+    decode_json_obj(val.get(), *iter);
+  } catch (err& e) {
+    val.reset();
+    string s = string(name) + ": ";
+    s.append(e.message);
+    throw err(s);
+  }
+
+  return true;
+}
+
 template<class T>
 static void encode_json(const char *name, const T& val, ceph::Formatter *f)
 {
@@ -574,6 +604,10 @@ public:
   long long val_long_long() const;
   bool val_bool() const;
 
+  const map<std::string, JSONFormattable> object() const {
+    return obj;
+  }
+
   const vector<JSONFormattable>& array() const {
     return arr;
   }
index d056c0287015ae29c37d5d34909139d8e4baf734..7470e5cb5db087f5e13390a11a718f9b79e37e85 100644 (file)
@@ -4780,20 +4780,15 @@ int main(int argc, const char **argv)
           RGWZonePlacementInfo& info = zone.placement_pools[placement_id];
 
           info.index_pool = *index_pool;
-          if (storage_class.empty()) {
-            info.data_pools[RGW_STORAGE_CLASS_STANDARD] = *data_pool;
-          } else {
-            info.data_pools[storage_class] = *data_pool;
-          }
+          rgw_pool dp = data_pool.get();
+          info.storage_classes.set_storage_class(storage_class, &dp, compression_type.get_ptr());
+
           if (data_extra_pool) {
             info.data_extra_pool = *data_extra_pool;
           }
           if (index_type_specified) {
             info.index_type = placement_index_type;
           }
-          if (compression_type) {
-            info.compression_type = *compression_type;
-          }
 
           ret = check_pool_support_omap(info.get_data_extra_pool());
           if (ret < 0) {
@@ -4812,22 +4807,15 @@ int main(int argc, const char **argv)
           if (index_pool && !index_pool->empty()) {
             info.index_pool = *index_pool;
           }
-          if (data_pool && !data_pool->empty()) {
-            if (storage_class.empty()) {
-              info.data_pools[RGW_STORAGE_CLASS_STANDARD] = *data_pool;
-            } else {
-              info.data_pools[storage_class] = *data_pool;
-            }
-          }
+          rgw_pool dp = data_pool.get();
+          info.storage_classes.set_storage_class(storage_class, &dp, compression_type.get_ptr());
+
           if (data_extra_pool) {
             info.data_extra_pool = *data_extra_pool;
           }
           if (index_type_specified) {
             info.index_type = placement_index_type;
           }
-          if (compression_type) {
-            info.compression_type = *compression_type;
-          }
           
           ret = check_pool_support_omap(info.get_data_extra_pool());
           if (ret < 0) {
index 448e6012f1f309a1d976c6a0666ed7b31d59a242..ff54299ce3ee6a38be887d288af5df4f201245fa 100644 (file)
@@ -964,32 +964,76 @@ void RGWZoneParams::dump(Formatter *f) const
   encode_json("realm_id", realm_id, f);
 }
 
+void RGWZoneStorageClass::dump(Formatter *f) const
+{
+  if (data_pool) {
+    encode_json("data_pool", data_pool.get(), f);
+  }
+  if (compression_type) {
+    encode_json("compression_type", compression_type.get(), f);
+  }
+}
+
+void RGWZoneStorageClass::decode_json(JSONObj *obj)
+{
+  JSONDecoder::decode_json("data_pool", data_pool, obj);
+  JSONDecoder::decode_json("compression_type", compression_type, obj);
+}
+
+void RGWZoneStorageClasses::dump(Formatter *f) const
+{
+  for (auto& i : m) {
+    encode_json(i.first.c_str(), i.second, f);
+  }
+}
+
+void RGWZoneStorageClasses::decode_json(JSONObj *obj)
+{
+  JSONFormattable f;
+  decode_json_obj(f, obj);
+
+  for (auto& field : f.object()) {
+    JSONObj *field_obj = obj->find_obj(field.first);
+    assert(field_obj);
+
+    decode_json_obj(m[field.first], field_obj);
+  }
+}
+
 void RGWZonePlacementInfo::dump(Formatter *f) const
 {
   encode_json("index_pool", index_pool, f);
-  encode_json("data_pools", data_pools, f);
+  encode_json("storage_classes", storage_classes, f);
   encode_json("data_extra_pool", data_extra_pool, f);
   encode_json("index_type", (uint32_t)index_type, f);
-  encode_json("compression", compression_type, f);
+
+  /* no real need for backward compatibility of compression_type and data_pool in here,
+   * rather not clutter the output */
 }
 
 void RGWZonePlacementInfo::decode_json(JSONObj *obj)
 {
   JSONDecoder::decode_json("index_pool", index_pool, obj);
-  JSONDecoder::decode_json("data_pools", data_pools, obj);
-  if (JSONDecoder::decode_json("data_pool", standard_data_pool, obj)) {
-    data_pools[RGW_STORAGE_CLASS_STANDARD] = standard_data_pool;
-  } else {
-    auto iter = data_pools.find(RGW_STORAGE_CLASS_STANDARD);
-    if (iter != data_pools.end()) {
-      standard_data_pool = iter->second;
-    }
-  }
+  JSONDecoder::decode_json("storage_classes", storage_classes, obj);
   JSONDecoder::decode_json("data_extra_pool", data_extra_pool, obj);
   uint32_t it;
   JSONDecoder::decode_json("index_type", it, obj);
   index_type = (RGWBucketIndexType)it;
-  JSONDecoder::decode_json("compression", compression_type, obj);
+
+  /* backward compatibility, these are now defined in storage_classes */
+  string standard_compression_type;
+  string *pcompression = nullptr;
+  if (JSONDecoder::decode_json("compression", standard_compression_type, obj)) {
+    pcompression = &standard_compression_type;
+  }
+  rgw_pool standard_data_pool;
+  rgw_pool *ppool = nullptr;
+  if (JSONDecoder::decode_json("data_pool", standard_data_pool, obj)) {
+    ppool = &standard_data_pool;
+  }
+  if (ppool || pcompression) {
+    storage_classes.set_storage_class(RGW_STORAGE_CLASS_STANDARD, ppool, pcompression);
+  }
 }
 
 void RGWZoneParams::decode_json(JSONObj *obj)
index 6a7d0599524e46f39171147ff7ff123f12d366c9..5a0476a737e8397a2eb5f009103cb19541650721 100644 (file)
@@ -3865,7 +3865,7 @@ void RGWPostObj::execute()
       filter = encrypt.get();
     } else {
       const auto& compression_type = store->svc.zone->get_zone_params().get_compression_type(
-          s->bucket_info.placement_rule.name);
+          s->bucket_info.placement_rule);
       if (compression_type != "none") {
         plugin = Compressor::create(s->cct, compression_type);
         if (!plugin) {
@@ -6586,9 +6586,8 @@ int RGWBulkUploadOp::handle_file(const boost::string_ref path,
   /* No filters by default. */
   DataProcessor *filter = &processor;
 
-#warning add storage_class compression
   const auto& compression_type = store->svc.zone->get_zone_params().get_compression_type(
-      binfo.placement_rule.name);
+      binfo.placement_rule);
   CompressorRef plugin;
   boost::optional<RGWPutObj_Compress> compressor;
   if (compression_type != "none") {
index 984c026d2a36d58f9eb5125de654734a97fe062c..799679481023aef229dee0e81d8fbbfef01e427e 100644 (file)
@@ -2891,7 +2891,7 @@ int RGWRados::create_bucket(const RGWUserInfo& owner, rgw_bucket& bucket,
   return -ENOENT;
 }
 
-bool RGWRados::get_obj_data_pool(const string& placement_rule, const rgw_obj& obj, rgw_pool *pool)
+bool RGWRados::get_obj_data_pool(const rgw_placement_rule& placement_rule, const rgw_obj& obj, rgw_pool *pool)
 {
   return rgw_get_obj_data_pool(svc.zone->get_zonegroup(), svc.zone->get_zone_params(), placement_rule, obj, pool);
 }
@@ -4260,9 +4260,8 @@ int RGWRados::fetch_remote_obj(RGWObjectCtx& obj_ctx,
   boost::optional<RGWPutObj_Compress> compressor;
   CompressorRef plugin;
 
-#warning compression type
   const auto& compression_type = svc.zone->get_zone_params().get_compression_type(
-      dest_bucket_info.placement_rule.name);
+      dest_bucket_info.placement_rule);
   if (compression_type != "none") {
     plugin = Compressor::create(cct, compression_type);
     if (!plugin) {
index e8acf3078070c660a10f887b0e68b4f8081cff43..7c9f414ca17da38be0e34ce56013729a30f72296 100644 (file)
@@ -1547,8 +1547,10 @@ int get_zones_pool_set(CephContext* cct,
       pool_names.insert(zone.reshard_pool);
       for(auto& iter : zone.placement_pools) {
        pool_names.insert(iter.second.index_pool);
-        for (auto& pi : iter.second.data_pools) {
-          pool_names.insert(pi.second);
+        for (auto& pi : iter.second.storage_classes.get_all()) {
+          if (pi.second.data_pool) {
+            pool_names.insert(pi.second.data_pool.get());
+          }
         }
        pool_names.insert(iter.second.data_extra_pool);
       }
@@ -1623,9 +1625,12 @@ int RGWZoneParams::fix_pool_names()
   for(auto& iter : placement_pools) {
     iter.second.index_pool = fix_zone_pool_dup(pools, name, "." + default_bucket_index_pool_suffix,
                                                iter.second.index_pool);
-    for (auto& pi : iter.second.data_pools) {
-      pi.second = fix_zone_pool_dup(pools, name, "." + default_storage_pool_suffix,
-                                                pi.second);
+    for (auto& pi : iter.second.storage_classes.get_all()) {
+      if (pi.second.data_pool) {
+        rgw_pool& pool = pi.second.data_pool.get();
+        pool = fix_zone_pool_dup(pools, name, "." + default_storage_pool_suffix,
+                                 pool);
+      }
     }
     iter.second.data_extra_pool= fix_zone_pool_dup(pools, name, "." + default_storage_extra_pool_suffix,
                                                    iter.second.data_extra_pool);
@@ -1646,7 +1651,8 @@ int RGWZoneParams::create(bool exclusive)
     /* a new system, let's set new placement info */
     RGWZonePlacementInfo default_placement;
     default_placement.index_pool = name + "." + default_bucket_index_pool_suffix;
-    default_placement.data_pools[RGW_STORAGE_CLASS_STANDARD] =  name + "." + default_storage_pool_suffix;
+    rgw_pool pool = name + "." + default_storage_pool_suffix;
+    default_placement.storage_classes.set_storage_class(RGW_STORAGE_CLASS_STANDARD, &pool, nullptr);
     default_placement.data_extra_pool = name + "." + default_storage_extra_pool_suffix;
     placement_pools["default-placement"] = default_placement;
   }
@@ -1746,14 +1752,14 @@ int RGWZoneParams::set_as_default(bool exclusive)
   return RGWSystemMetaObj::set_as_default(exclusive);
 }
 
-const string& RGWZoneParams::get_compression_type(const string& placement_rule) const
+const string& RGWZoneParams::get_compression_type(const rgw_placement_rule& placement_rule) const
 {
   static const std::string NONE{"none"};
-  auto p = placement_pools.find(placement_rule);
+  auto p = placement_pools.find(placement_rule.name);
   if (p == placement_pools.end()) {
     return NONE;
   }
-  const auto& type = p->second.compression_type;
+  const auto& type = p->second.get_compression_type(placement_rule.storage_class);
   return !type.empty() ? type : NONE;
 }
 
index d50e69dcb719d9a26dec5521e893475ec66b1e4b..3b4a4d0b668a12dff60888cc05ea8f26457853f6 100644 (file)
@@ -151,36 +151,131 @@ public:
 };
 WRITE_CLASS_ENCODER(RGWSystemMetaObj)
 
+struct RGWZoneStorageClass {
+  boost::optional<rgw_pool> data_pool;
+  boost::optional<std::string> compression_type;
+
+  void encode(bufferlist& bl) const {
+    ENCODE_START(1, 1, bl);
+    encode(data_pool, bl);
+    encode(compression_type, bl);
+    ENCODE_FINISH(bl);
+  }
+
+  void decode(bufferlist::const_iterator& bl) {
+    DECODE_START(1, bl);
+    decode(data_pool, bl);
+    decode(compression_type, bl);
+    DECODE_FINISH(bl);
+  }
+
+  void dump(Formatter *f) const;
+  void decode_json(JSONObj *obj);
+};
+WRITE_CLASS_ENCODER(RGWZoneStorageClass)
+
+
+class RGWZoneStorageClasses {
+  map<string, RGWZoneStorageClass> m;
+
+  /* in memory only */
+  RGWZoneStorageClass *standard_class{&m[RGW_STORAGE_CLASS_STANDARD]};
+
+public:
+  RGWZoneStorageClasses() {}
+  RGWZoneStorageClasses(const RGWZoneStorageClasses& rhs) {
+    m = rhs.m;
+    standard_class = &m[RGW_STORAGE_CLASS_STANDARD];
+  }
+  RGWZoneStorageClasses& operator=(const RGWZoneStorageClasses& rhs) {
+    m = rhs.m;
+    standard_class = &m[RGW_STORAGE_CLASS_STANDARD];
+    return *this;
+  }
+
+  const RGWZoneStorageClass& get_standard() const {
+    return *standard_class;
+  }
+
+  bool find(const string& sc, const RGWZoneStorageClass **pstorage_class) const {
+    auto iter = m.find(sc);
+    if (iter == m.end()) {
+      return false;
+    }
+    *pstorage_class = &iter->second;
+    return true;
+  }
+
+  const map<string, RGWZoneStorageClass>& get_all() const {
+    return m;
+  }
+
+  map<string, RGWZoneStorageClass>& get_all() {
+    return m;
+  }
+
+  void set_storage_class(const string& sc, const rgw_pool *data_pool, const string *compression_type) {
+    const string *psc = &sc;
+    if (sc.empty()) {
+      psc = &RGW_STORAGE_CLASS_STANDARD;
+    }
+    RGWZoneStorageClass& storage_class = m[*psc];
+    if (data_pool) {
+      storage_class.data_pool = *data_pool;
+    }
+    if (compression_type) {
+      storage_class.compression_type = *compression_type;
+    }
+  }
+
+  void encode(bufferlist& bl) const {
+    ENCODE_START(1, 1, bl);
+    encode(m, bl);
+    ENCODE_FINISH(bl);
+  }
+
+  void decode(bufferlist::const_iterator& bl) {
+    DECODE_START(1, bl);
+    decode(m, bl);
+    DECODE_FINISH(bl);
+  }
+
+  void dump(Formatter *f) const;
+  void decode_json(JSONObj *obj);
+};
+WRITE_CLASS_ENCODER(RGWZoneStorageClasses)
+
 struct RGWZonePlacementInfo {
   rgw_pool index_pool;
-  rgw_pool standard_data_pool;
   rgw_pool data_extra_pool; /* if not set we should use data_pool */
-  map<string, rgw_pool> data_pools;
+  RGWZoneStorageClasses storage_classes;
   RGWBucketIndexType index_type;
-  std::string compression_type;
 
   RGWZonePlacementInfo() : index_type(RGWBIType_Normal) {}
 
   void encode(bufferlist& bl) const {
     ENCODE_START(7, 1, bl);
     encode(index_pool.to_str(), bl);
-    encode(data_pool.to_str(), bl);
+    rgw_pool standard_data_pool = get_data_pool(RGW_STORAGE_CLASS_STANDARD);
+    encode(standard_data_pool.to_str(), bl);
     encode(data_extra_pool.to_str(), bl);
     encode((uint32_t)index_type, bl);
-    encode(compression_type, bl);
+    string standard_compression_type = get_compression_type(RGW_STORAGE_CLASS_STANDARD);
+    encode(standard_compression_type, bl);
+    encode(storage_classes, bl);
     ENCODE_FINISH(bl);
   }
 
   void decode(bufferlist::const_iterator& bl) {
-    DECODE_START(6, bl);
-    std::string index_pool_str;
-    std::string data_pool_str;
+    DECODE_START(7, bl);
+    string index_pool_str;
+    string data_pool_str;
     decode(index_pool_str, bl);
     index_pool = rgw_pool(index_pool_str);
     decode(data_pool_str, bl);
-    data_pool = rgw_pool(data_pool_str);
+    rgw_pool standard_data_pool(data_pool_str);
     if (struct_v >= 4) {
-      std::string data_extra_pool_str;
+      string data_extra_pool_str;
       decode(data_extra_pool_str, bl);
       data_extra_pool = rgw_pool(data_extra_pool_str);
     }
@@ -189,19 +284,49 @@ struct RGWZonePlacementInfo {
       decode(it, bl);
       index_type = (RGWBucketIndexType)it;
     }
+    string standard_compression_type;
     if (struct_v >= 6) {
-      decode(compression_type, bl);
+      decode(standard_compression_type, bl);
+    }
+    if (struct_v >= 7) {
+      decode(storage_classes, bl);
+    } else {
+      storage_classes.set_storage_class(RGW_STORAGE_CLASS_STANDARD, &standard_data_pool,
+                                        (!standard_compression_type.empty() ? &standard_compression_type : nullptr));
     }
     DECODE_FINISH(bl);
   }
   const rgw_pool& get_data_extra_pool() const {
+    static rgw_pool no_pool;
     if (data_extra_pool.empty()) {
-      return data_pool;
+      return storage_classes.get_standard().data_pool.get_value_or(no_pool);
     }
     return data_extra_pool;
   }
+  const rgw_pool& get_data_pool(const string& sc) const {
+    const RGWZoneStorageClass *storage_class;
+    static rgw_pool no_pool;
+
+    if (!storage_classes.find(sc, &storage_class)) {
+      return storage_classes.get_standard().data_pool.get_value_or(no_pool);
+    }
+
+    return storage_class->data_pool.get_value_or(no_pool);
+  }
+
+  const string& get_compression_type(const string& sc) const {
+    const RGWZoneStorageClass *storage_class;
+    static string no_compression;
+
+    if (!storage_classes.find(sc, &storage_class)) {
+      return no_compression;
+    }
+    return storage_class->compression_type.get_value_or(no_compression);
+  }
+
   void dump(Formatter *f) const;
   void decode_json(JSONObj *obj);
+
 };
 WRITE_CLASS_ENCODER(RGWZonePlacementInfo)
 
@@ -252,7 +377,7 @@ struct RGWZoneParams : RGWSystemMetaObj {
   int create(bool exclusive = true) override;
   int fix_pool_names();
 
-  const std::string& get_compression_type(const std::string& placement_rule) const;
+  const string& get_compression_type(const rgw_placement_rule& placement_rule) const;
   
   void encode(bufferlist& bl) const override {
     ENCODE_START(12, 1, bl);
index d6717ef08f7fb50df6ac8e0cc72d7d7d5598af27..aa3d745808442ce5ea12eab7d3e6500b35637268 100644 (file)
@@ -1132,7 +1132,9 @@ read_omap:
   }
   pool_name = miter->first;
 
-  rule_info->data_pools[RGW_STORAGE_CLASS_STANDARD] = pool_name;
+  rgw_pool pool = pool_name;
+
+  rule_info->storage_classes.set_storage_class(RGW_STORAGE_CLASS_STANDARD, &pool, nullptr);
   rule_info->data_extra_pool = pool_name;
   rule_info->index_pool = pool_name;
   rule_info->index_type = RGWBIType_Normal;