]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
os/bluestore: refactors expand_devices for online and offline use
authorJoshua Blanch <joshua.blanch@clyso.com>
Tue, 6 Jan 2026 23:58:24 +0000 (23:58 +0000)
committerJoshua Blanch <joshua.blanch@clyso.com>
Thu, 23 Apr 2026 15:05:55 +0000 (15:05 +0000)
Refactors device expansion to use a expand_devices()
that handles both online (admin socket) and offline (ceph-bluestore-tool)
use cases.

Signed-off-by: Joshua Blanch <joshua.blanch@clyso.com>
src/os/bluestore/BlueAdmin.cc
src/os/bluestore/BlueStore.cc
src/os/bluestore/BlueStore.h

index e647b7bb85e386507cf3b8dd27db5c8393d36122..da05ecf14cb98d39e9032e0ed791ff1777038725 100644 (file)
@@ -298,7 +298,7 @@ int BlueStore::SocketHook::call(
     return 0;
   } else if (command == "bluestore bluefs-bdev-expand"){
     std::stringstream result;
-    int ret = store.expand_devices_online(result);
+    int ret = store.expand_devices(result);
     if (ret < 0) {
       ss << "expand device failed: " << cpp_strerror(ret) << std::endl;
     } else {
index 46b8ccaa6f990c7a26fb3c41574c51e03c18f464..f93342b2b822ee36eb771f6818b56ff53fe50adf 100644 (file)
@@ -9184,135 +9184,6 @@ string BlueStore::get_device_path(unsigned id)
   return res;
 }
 
-int BlueStore::expand_devices(ostream& out)
-{
-  // let's open in read-only mode first to be able to recover
-  // from the out-of-space state at DB/shared volume(s)
-  // Opening in R/W mode might cause extra space allocation
-  // which is effectively a show stopper for volume expansion.
-  int r = _open_db_and_around(true);
-  ceph_assert(r == 0);
-  bluefs->dump_block_extents(out);
-  out << "Expanding DB/WAL..." << std::endl;
-  // updating dedicated devices first
-  for (auto devid : { BlueFS::BDEV_WAL, BlueFS::BDEV_DB}) {
-    if (devid == bluefs_layout.shared_bdev) {
-      continue;
-    }
-    auto my_bdev = bluefs->get_block_device(devid);
-    uint64_t size = my_bdev ? my_bdev->get_size() : 0;
-    if (size == 0) {
-      // no bdev
-      continue;
-    }
-    if (my_bdev->supported_bdev_label()) {
-      string my_path = get_device_path(devid);
-      bluestore_bdev_label_t my_label;
-      int r = _read_bdev_label(cct, my_bdev, my_path, &my_label);
-      if (r < 0) {
-        derr << "unable to read label for " << my_path << ": "
-              << cpp_strerror(r) << dendl;
-        continue;
-      } else {
-        if (size == my_label.size) {
-          // no need to expand
-          out << devid
-             << " : nothing to do, skipped"
-             << std::endl;
-          continue;
-        } else if (size < my_label.size) {
-          // something weird in bdev label
-          out << devid
-             <<" : ERROR: bdev label is above device size, skipped"
-             << std::endl;
-          continue;
-        } else {
-          my_label.size = size;
-          out << devid
-             << " : Expanding to 0x" << std::hex << size
-             << std::dec << "(" << byte_u_t(size) << ")"
-             << std::endl;
-          r = _write_bdev_label(cct, my_bdev, my_path, my_label);
-          if (r < 0) {
-            derr << "unable to write label for " << my_path << ": "
-                  << cpp_strerror(r) << dendl;
-          } else {
-            out << devid
-                << " : size updated to 0x" << std::hex << size
-                << std::dec << "(" << byte_u_t(size) << ")"
-                << std::endl;
-          }
-        }
-      }
-    }
-  }
-  // now proceed with a shared device
-  uint64_t size0 = fm->get_size();
-  uint64_t size = bdev->get_size();
-  auto devid = bluefs_layout.shared_bdev;
-  auto aligned_size = p2align(size, min_alloc_size);
-  if (aligned_size == size0) {
-    // no need to expand
-    out << devid
-        << " : nothing to do, skipped"
-        << std::endl;
-  } else if (aligned_size < size0) {
-    // something weird in bdev label
-    out << devid
-        << " : ERROR: previous device size is above the current one, skipped"
-       << std::endl;
-  } else {
-    auto my_path = get_device_path(devid);
-    out << devid
-       <<" : Expanding to 0x" << std::hex << size
-       << std::dec << "(" << byte_u_t(size) << ")"
-       << std::endl;  
-    r = _write_out_fm_meta(size);
-    if (r != 0) {
-      derr << "unable to write out fm meta for " << my_path << ": "
-           << cpp_strerror(r) << dendl;
-    } else if (bdev->supported_bdev_label()) {
-      bdev_label.size = size;
-      uint64_t lsize = std::max(BDEV_LABEL_BLOCK_SIZE, min_alloc_size);
-      for (uint64_t loc : bdev_label_positions) {
-        if ((loc >= size0) && (loc + lsize <= size)) {
-          bdev_label_valid_locations.push_back(loc);
-          if (!bdev_label_multi) {
-            break;
-          }
-        }
-      }
-      r = _write_bdev_label(cct, bdev, my_path,
-        bdev_label, bdev_label_valid_locations);
-      if (r != 0) {
-        derr << "unable to write label(s) for " << my_path << ": "
-             << cpp_strerror(r) << dendl;
-      }
-    }
-    if (r == 0) {
-      out << devid
-          << " : size updated to 0x" << std::hex << size
-          << std::dec << "(" << byte_u_t(size) << ")"
-          << std::endl;
-      _close_db_and_around();
-
-       //
-      // Mount in read/write to sync expansion changes
-      // and make sure everything is all right.
-      //
-      before_expansion_bdev_size = size0; // preserve orignal size to permit
-                                          // following _db_open_and_around()
-                                          // do some post-init stuff on opened
-                                          // allocator.
-
-      r = _open_db_and_around(false);
-      ceph_assert(r == 0);
-    }
-  }
-  _close_db_and_around();
-  return r;
-}
-
 bool BlueStore::get_db_sharding(std::string& res_sharding)
 {
   bool ret = false;
@@ -9323,8 +9194,24 @@ bool BlueStore::get_db_sharding(std::string& res_sharding)
   return ret;
 }
 
-int BlueStore::expand_devices_online(ostream& out)
+int BlueStore::expand_devices(ostream& out)
 {
+  bool need_to_close = false;
+  int r = 0;
+
+  if (!mounted) {
+    // let's open in read-only mode first to be able to recover
+    // from the out-of-space state at DB/shared volume(s)
+    // Opening in R/W mode might cause extra space allocation
+    // which is effectively a show stopper for volume expansion.
+    r = _open_db_and_around(false);
+    if (r < 0) {
+      derr << __func__ << " failed to open db: " << cpp_strerror(r) << dendl;
+      return r;
+    }
+    need_to_close = true;
+  }
+
   bluefs->dump_block_extents(out);
   out << "Expanding DB/WAL..." << std::endl;
 
@@ -9345,7 +9232,7 @@ int BlueStore::expand_devices_online(ostream& out)
     if (my_bdev->supported_bdev_label()) {
       string my_path = get_device_path(devid);
       bluestore_bdev_label_t my_label;
-      int r = _read_bdev_label(cct, my_bdev, my_path, &my_label);
+      r = _read_bdev_label(cct, my_bdev, my_path, &my_label);
       if (r < 0) {
         derr << "unable to read label for " << my_path << ": "
               << cpp_strerror(r) << dendl;
@@ -9380,7 +9267,9 @@ int BlueStore::expand_devices_online(ostream& out)
                 << std::dec << "(" << byte_u_t(size) << ")"
                 << std::endl;
           }
-          bluefs->expand_device(devid, size, old_size);
+          if (mounted) {
+            bluefs->expand_device(devid, size, old_size);
+          }
         }
       }
     }
@@ -9394,7 +9283,7 @@ int BlueStore::expand_devices_online(ostream& out)
   uint64_t size0 = fm->get_size();
   uint64_t size = bdev->get_size();
   auto aligned_size = p2align(size, min_alloc_size);
-  int r = 0;
+  r = 0;
   if (aligned_size == size0) {
     // no need to expand
     out << devid
@@ -9410,7 +9299,7 @@ int BlueStore::expand_devices_online(ostream& out)
     out << devid
        <<" : Expanding to 0x" << std::hex << size
        << std::dec << "(" << byte_u_t(size) << ")"
-       << std::endl;  
+       << std::endl;
     r = _write_out_fm_meta(size);
     if (r != 0) {
       derr << "unable to write out fm meta for " << my_path << ": "
@@ -9428,6 +9317,10 @@ int BlueStore::expand_devices_online(ostream& out)
       }
       r = _write_bdev_label(cct, bdev, my_path,
         bdev_label, bdev_label_valid_locations);
+      if (r != 0) {
+        derr << "unable to write label(s) for " << my_path << ": "
+             << cpp_strerror(r) << dendl;
+      }
     }
     if (r == 0) {
       out << devid
@@ -9435,27 +9328,26 @@ int BlueStore::expand_devices_online(ostream& out)
           << std::dec << "(" << byte_u_t(size) << ")"
           << std::endl;
 
-      // since we are not relying on db open/close to update FM
-      // need to keep FM and the shared allocator in sync now
       fm->expand(aligned_size, db);
       alloc->expand(aligned_size);
       alloc->init_add_free(size0, aligned_size - size0);
 
-      need_to_destage_allocation_file = true;
-      before_expansion_bdev_size = 0;
-
       dout(1) << __func__
               << " : size updated to 0x" << std::hex << size
               << std::dec << "(" << byte_u_t(size) << ")"
               << ", allocator type " << alloc->get_type()
-              << ", capacity 0x" << alloc->get_capacity()
+              << ", capacity 0x" << std::hex << alloc->get_capacity()
               << ", block size 0x" << alloc->get_block_size()
               << ", free 0x" << alloc->get_free()
+              << std::dec
               << ", fragmentation " << alloc->get_fragmentation()
-              << std::dec << dendl;
-
+              << dendl;
     }
   }
+
+  if (need_to_close) {
+    _close_db_and_around();
+  }
   return r;
 }
 
index b00ceab5c5e69cb762c8d979d79180bbac6a3c24..19111a19432dd28e69520f85af038d32204a2250 100644 (file)
@@ -3207,7 +3207,6 @@ public:
     int id,
     const std::string& path);
   int expand_devices(std::ostream& out);
-  int expand_devices_online(std::ostream& out);
   std::string get_device_path(unsigned id);
 
   bool get_db_sharding(std::string& res_sharding);