]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
tool/bluestore-tool: add zap_device command support
authorIgor Fedotov <igor.fedotov@croit.io>
Fri, 6 Sep 2024 09:46:01 +0000 (12:46 +0300)
committerAdam Kupczyk <akupczyk@ibm.com>
Wed, 25 Sep 2024 06:12:33 +0000 (06:12 +0000)
Signed-off-by: Igor Fedotov <igor.fedotov@croit.io>
(cherry picked from commit c9c30bcdb07b6d32c94d5438d6b2fd3dfb11ce14)

Conflicts:
src/os/bluestore/BlueStore.cc
src/os/bluestore/BlueStore.h
src/os/bluestore/bluestore_tool.cc
Trivial conflicts with non-existent 'trim' feature.

src/os/bluestore/BlueStore.cc
src/os/bluestore/BlueStore.h
src/os/bluestore/bluestore_tool.cc

index 90cedb90abaeea38266f6547ede005b085c7496c..33b489cf48bee0569f9637e3617b4acea486743f 100644 (file)
@@ -8891,6 +8891,55 @@ int BlueStore::dump_bluefs_sizes(ostream& out)
   return r;
 }
 
+int BlueStore::zap_device(CephContext* cct, const string& dev, uint64_t gap_size)
+{
+  string path; // dummy var for dout
+  dout(5)<<  __func__ << " " << dev << dendl;
+  auto * _bdev =
+    BlockDevice::create(cct, dev, nullptr, nullptr, nullptr, nullptr);
+  int r = _bdev->open(dev);
+  if (r < 0)
+    goto fail;
+  if (!gap_size) {
+    gap_size = _bdev->get_block_size();
+  }
+  if (p2align(gap_size, _bdev->get_block_size()) != gap_size) {
+    derr << __func__
+         << " zapping size has to be aligned with device block size: 0x" 
+         << std::hex << gap_size << " vs. 0x" << _bdev->get_block_size()
+         << std::dec << dendl;
+    return -EINVAL;
+  }
+  for (auto off : bdev_label_positions) {
+    uint64_t end = std::min(off + gap_size, _bdev->get_size());
+    if (end > off) {
+      uint64_t l = end - off;
+      bufferlist bl;
+      bl.append_zero(l);
+      dout(10) << __func__ << " writing 0x"
+               << std::hex << off << "~" << l
+               << std::dec << " to " << dev
+               <<  dendl;
+      r = _bdev->write(off, bl, false);
+      if (r < 0) {
+        derr << __func__ << " error writing 0x"
+             << std::hex << off << "~" << l
+             << std::dec << " to " << dev
+             << " : " << cpp_strerror(r) <<  dendl;
+        break;
+      }
+    } else {
+      break;
+    }
+  }
+
+fail_close:
+  _bdev->close();
+
+fail:
+  return r;
+}
+
 void BlueStore::set_cache_shards(unsigned num)
 {
   dout(10) << __func__ << " " << num << dendl;
index cb689d2ea2bf01794f14a66b34eb8f687ba50b13..224620a620c30be41f617469351ce8e1cee15595 100644 (file)
@@ -3084,6 +3084,7 @@ public:
   std::string get_device_path(unsigned id);
 
   int dump_bluefs_sizes(std::ostream& out);
+  static int zap_device(CephContext* cct, const std::string& dev, uint64_t gap_size);
 
 public:
   int statfs(struct store_statfs_t *buf,
index a478efc27784278af175d64be435127984e2c295..25b2e9774552ee3ee8a7c40287b66d9dd112e8de 100644 (file)
@@ -289,6 +289,7 @@ int main(int argc, char **argv)
   string new_sharding = empty_sharding;
   string resharding_ctrl;
   int log_level = 30;
+  uint64_t zap_size = 0;
   bool fsck_deep = false;
   po::options_description po_options("Options");
   po_options.add_options()
@@ -310,6 +311,7 @@ int main(int argc, char **argv)
     ("yes-i-really-really-mean-it", "additional confirmation for dangerous commands")
     ("sharding", po::value<string>(&new_sharding), "new sharding to apply")
     ("resharding-ctrl", po::value<string>(&resharding_ctrl), "gives control over resharding procedure details")
+    ("zap-size", po::value<uint64_t>(&zap_size), "size of a block written when zapping device")
     ;
   po::options_description po_positional("Positional options");
   po_positional.add_options()
@@ -337,7 +339,9 @@ int main(int argc, char **argv)
         "free-fragmentation, "
         "bluefs-stats, "
         "reshard, "
-        "show-sharding")
+        "show-sharding, "
+        "zap-device"
+)
     ;
   po::options_description po_all("All options");
   po_all.add(po_options).add(po_positional);
@@ -553,6 +557,18 @@ int main(int argc, char **argv)
       exit(EXIT_FAILURE);
     }
   }
+  if (action == "zap-device") {
+    if (devs.empty()) {
+      cerr << "must specify device(s) with --dev option" << std::endl;
+      exit(EXIT_FAILURE);
+    }
+    if (!vm.count("yes-i-really-really-mean-it")) {
+      cerr << "zap-osd is a DESTRUCTIVE operation, it causes OSD data loss, "
+           << "please confirm with --yes-i-really-really-mean-it option"
+           << std::endl;
+      exit(EXIT_FAILURE);
+    }
+  }
 
   if (action == "restore_cfb") {
 #ifndef CEPH_BLUESTORE_TOOL_RESTORE_ALLOCATION
@@ -1188,6 +1204,14 @@ int main(int argc, char **argv)
       exit(EXIT_FAILURE);
     }
     cout << sharding << std::endl;
+  } else if (action == "zap-device") {
+    for(auto& dev : devs) {
+      int r = BlueStore::zap_device(cct.get(), dev, zap_size);
+      if (r < 0) {
+        cerr << "error from zap: " << cpp_strerror(r) << std::endl;
+        exit(EXIT_FAILURE);
+      }
+    }
   } else {
     cerr << "unrecognized action " << action << std::endl;
     return 1;