]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
osd: adjust snapmapper keys on first start as octopus
authorSage Weil <sage@redhat.com>
Thu, 6 Jun 2019 19:37:07 +0000 (14:37 -0500)
committerSage Weil <sage@redhat.com>
Tue, 2 Jul 2019 13:37:49 +0000 (08:37 -0500)
Convert snapmapper keys to the new form the first time we start up running
octopus.

This is an incompat feature--once you start as octopus you can't go back.

Signed-off-by: Sage Weil <sage@redhat.com>
src/osd/OSD.cc
src/osd/SnapMapper.cc
src/osd/SnapMapper.h
src/osd/osd_types.h

index f85d33cead1a958b6e8385e897621c95ef4ab1a0..7c1aaacab179cc01e62cfef9a956f77c8b56a406 100644 (file)
@@ -198,6 +198,7 @@ CompatSet OSD::get_osd_initial_compat_set() {
   ceph_osd_feature_incompat.insert(CEPH_OSD_FEATURE_INCOMPAT_MISSING);
   ceph_osd_feature_incompat.insert(CEPH_OSD_FEATURE_INCOMPAT_FASTINFO);
   ceph_osd_feature_incompat.insert(CEPH_OSD_FEATURE_INCOMPAT_RECOVERY_DELETES);
+  ceph_osd_feature_incompat.insert(CEPH_OSD_FEATURE_INCOMPAT_SNAPMAPPER2);
   return CompatSet(ceph_osd_feature_compat, ceph_osd_feature_ro_compat,
                   ceph_osd_feature_incompat);
 }
@@ -2849,6 +2850,17 @@ int OSD::init()
   initial = get_osd_initial_compat_set();
   diff = superblock.compat_features.unsupported(initial);
   if (superblock.compat_features.merge(initial)) {
+    // Are we adding SNAPMAPPER2?
+    if (diff.incompat.contains(CEPH_OSD_FEATURE_INCOMPAT_SNAPMAPPER2)) {
+      dout(1) << __func__ << " upgrade snap_mapper (first start as octopus)"
+             << dendl;
+      auto ch = service.meta_ch;
+      auto hoid = make_snapmapper_oid();
+      unsigned max = cct->_conf->osd_target_transaction_size;
+      r = SnapMapper::convert_legacy(cct, store, ch, hoid, max);
+      if (r < 0)
+       goto out;
+    }
     // We need to persist the new compat_set before we
     // do anything else
     dout(5) << "Upgrading superblock adding: " << diff << dendl;
index e745fff23f6dbc01b9963885483d43f9d0de671b..968caff370b2e77eb363a723f22952d557acf712 100644 (file)
@@ -85,37 +85,6 @@ int OSDriver::get_next(
   }
 }
 
-struct Mapping {
-  snapid_t snap;
-  hobject_t hoid;
-  explicit Mapping(const pair<snapid_t, hobject_t> &in)
-    : snap(in.first), hoid(in.second) {}
-  Mapping() : snap(0) {}
-  void encode(bufferlist &bl) const {
-    ENCODE_START(1, 1, bl);
-    encode(snap, bl);
-    encode(hoid, bl);
-    ENCODE_FINISH(bl);
-  }
-  void decode(bufferlist::const_iterator &bl) {
-    DECODE_START(1, bl);
-    decode(snap, bl);
-    decode(hoid, bl);
-    DECODE_FINISH(bl);
-  }
-};
-WRITE_CLASS_ENCODER(Mapping)
-
-string SnapMapper::get_legacy_prefix(snapid_t snap)
-{
-  char buf[100];
-  int len = snprintf(
-    buf, sizeof(buf),
-    "%.*X_",
-    (int)(sizeof(snap)*2), static_cast<unsigned>(snap));
-  return LEGACY_MAPPING_PREFIX + string(buf, len);
-}
-
 string SnapMapper::get_prefix(int64_t pool, snapid_t snap)
 {
   char buf[100];
@@ -146,6 +115,7 @@ pair<string, bufferlist> SnapMapper::to_raw(
 pair<snapid_t, hobject_t> SnapMapper::from_raw(
   const pair<std::string, bufferlist> &image)
 {
+  using ceph::decode;
   Mapping map;
   bufferlist bl(image.second);
   auto bp = bl.cbegin();
@@ -428,3 +398,81 @@ int SnapMapper::get_snaps(
     snaps->swap(out.snaps);
   return 0;
 }
+
+
+// -------------------------------------
+// legacy conversion/support
+
+string SnapMapper::get_legacy_prefix(snapid_t snap)
+{
+  char buf[100];
+  int len = snprintf(
+    buf, sizeof(buf),
+    "%.*X_",
+    (int)(sizeof(snap)*2), static_cast<unsigned>(snap));
+  return LEGACY_MAPPING_PREFIX + string(buf, len);
+}
+
+string SnapMapper::to_legacy_raw_key(
+  const pair<snapid_t, hobject_t> &in)
+{
+  return get_legacy_prefix(in.first) + shard_prefix + in.second.to_str();
+}
+
+bool SnapMapper::is_legacy_mapping(const string &to_test)
+{
+  return to_test.substr(0, LEGACY_MAPPING_PREFIX.size()) ==
+    LEGACY_MAPPING_PREFIX;
+}
+
+int SnapMapper::convert_legacy(
+  CephContext *cct,
+  ObjectStore *store,
+  ObjectStore::CollectionHandle& ch,
+  ghobject_t hoid,
+  unsigned max)
+{
+  uint64_t n = 0;
+
+  ObjectMap::ObjectMapIterator iter = store->get_omap_iterator(ch, hoid);
+  if (!iter) {
+    return -EIO;
+  }
+
+  auto start = ceph::mono_clock::now();
+
+  iter->upper_bound(SnapMapper::LEGACY_MAPPING_PREFIX);
+  map<string,bufferlist> to_set;
+  while (iter->valid()) {
+    bool valid = SnapMapper::is_legacy_mapping(iter->key());
+    if (valid) {
+      SnapMapper::Mapping m;
+      bufferlist bl(iter->value());
+      auto bp = bl.cbegin();
+      decode(m, bp);
+      to_set.emplace(
+       SnapMapper::get_prefix(m.hoid.pool, m.snap),
+       bl);
+      ++n;
+      iter->next();
+    }
+    if (!valid || !iter->valid() || to_set.size() >= max) {
+      ObjectStore::Transaction t;
+      t.omap_setkeys(ch->cid, hoid, to_set);
+      int r = store->queue_transaction(ch, std::move(t));
+      ceph_assert(r == 0);
+      to_set.clear();
+      if (!valid) {
+       break;
+      }
+      dout(10) << __func__ << " converted " << n << " keys" << dendl;
+    }
+  }
+
+  auto end = ceph::mono_clock::now();
+
+  dout(1) << __func__ << " converted " << n << " keys in "
+         << timespan_str(end - start) << dendl;
+#warning fixme remove old keys
+  return 0;
+}
index 2a9236c1f90e8e7755defc59e5ea7af1e5cb9ee0..d8899b12f3469b553b4b33920f19727e2948a5a2 100644 (file)
@@ -111,16 +111,46 @@ public:
     void decode(bufferlist::const_iterator &bp);
   };
 
-private:
-  MapCacher::MapCacher<std::string, bufferlist> backend;
+  struct Mapping {
+    snapid_t snap;
+    hobject_t hoid;
+    explicit Mapping(const pair<snapid_t, hobject_t> &in)
+      : snap(in.first), hoid(in.second) {}
+    Mapping() : snap(0) {}
+    void encode(bufferlist &bl) const {
+      ENCODE_START(1, 1, bl);
+      encode(snap, bl);
+      encode(hoid, bl);
+      ENCODE_FINISH(bl);
+    }
+    void decode(bufferlist::const_iterator &bl) {
+      DECODE_START(1, bl);
+      decode(snap, bl);
+      decode(hoid, bl);
+      DECODE_FINISH(bl);
+    }
+  };
 
   static const std::string LEGACY_MAPPING_PREFIX;
   static const std::string MAPPING_PREFIX;
   static const std::string OBJECT_PREFIX;
 
+  static int convert_legacy(
+    CephContext *cct,
+    ObjectStore *store,
+    ObjectStore::CollectionHandle& ch,
+    ghobject_t hoid,
+    unsigned max);
+
+private:
+  MapCacher::MapCacher<std::string, bufferlist> backend;
+
   static std::string get_legacy_prefix(snapid_t snap);
-  static std::string get_prefix(int64_t pool, snapid_t snap);
+  std::string to_legacy_raw_key(
+    const std::pair<snapid_t, hobject_t> &to_map);
+  static bool is_legacy_mapping(const std::string &to_test);
 
+  static std::string get_prefix(int64_t pool, snapid_t snap);
   std::string to_raw_key(
     const std::pair<snapid_t, hobject_t> &to_map);
 
@@ -129,7 +159,7 @@ private:
 
   static bool is_mapping(const std::string &to_test);
 
-  std::pair<snapid_t, hobject_t> from_raw(
+  static std::pair<snapid_t, hobject_t> from_raw(
     const std::pair<std::string, bufferlist> &image);
 
   std::string to_object_key(const hobject_t &hoid);
@@ -234,5 +264,6 @@ public:
     ); ///< @return error, -ENOENT if oid is not recorded
 };
 WRITE_CLASS_ENCODER(SnapMapper::object_snaps)
+WRITE_CLASS_ENCODER(SnapMapper::Mapping)
 
 #endif
index 12042f2a400b04d5577ea77dd0749f61d7e95bbd..46b4c88117d8fd8a52f0cfbdfe74c2b816c5a8bc 100644 (file)
@@ -68,6 +68,7 @@
 #define CEPH_OSD_FEATURE_INCOMPAT_MISSING CompatSet::Feature(14, "explicit missing set")
 #define CEPH_OSD_FEATURE_INCOMPAT_FASTINFO CompatSet::Feature(15, "fastinfo pg attr")
 #define CEPH_OSD_FEATURE_INCOMPAT_RECOVERY_DELETES CompatSet::Feature(16, "deletes in missing set")
+#define CEPH_OSD_FEATURE_INCOMPAT_SNAPMAPPER2 CompatSet::Feature(17, "new snapmapper key structure")
 
 
 /// pool priority range set by user