]> git.apps.os.sepia.ceph.com Git - ceph-ci.git/commitdiff
os/bluestore/BlockDevice: add get_devname(), get_devices()
authorSage Weil <sage@redhat.com>
Fri, 20 Oct 2017 22:11:39 +0000 (17:11 -0500)
committerSage Weil <sage@redhat.com>
Tue, 31 Oct 2017 17:30:43 +0000 (12:30 -0500)
Enumerate device(s) that we are backed by.  It may be plural because of
DM, which might mask an underlying device, or because the dm device is
combining multiple other devices.

Signed-off-by: Sage Weil <sage@redhat.com>
src/common/blkdev.cc
src/common/blkdev.h
src/os/bluestore/BlockDevice.h
src/os/bluestore/KernelDevice.cc
src/os/bluestore/KernelDevice.h

index d95a397a8441afd37fef8a3f57806fc9a5ebfff9..c71a05bd2b47d0124b588ad821e94b2ca88e9bee 100644 (file)
@@ -263,6 +263,38 @@ int get_device_by_fd(int fd, char *partition, char *device, size_t max)
   return 0;
 }
 
+static int easy_readdir(const std::string& dir, std::set<std::string> *out)
+{
+  DIR *h = ::opendir(dir.c_str());
+  if (!h) {
+    return -errno;
+  }
+  struct dirent *de = nullptr;
+  while ((de = ::readdir(h))) {
+    if (strcmp(de->d_name, ".") == 0 ||
+       strcmp(de->d_name, "..") == 0) {
+      continue;
+    }
+    out->insert(de->d_name);
+  }
+  closedir(h);
+  return 0;
+}
+
+void get_dm_parents(const std::string& dev, std::set<std::string> *ls)
+{
+  std::string p = std::string("/sys/block/") + dev + "/slaves";
+  std::set<std::string> parents;
+  easy_readdir(p, &parents);
+  for (auto& d : parents) {
+    ls->insert(d);
+    // recurse in case it is dm-on-dm
+    if (d.find("dm-") == 0) {
+      get_dm_parents(d, ls);
+    }
+  }
+}
+
 #elif defined(__APPLE__)
 #include <sys/disk.h>
 
@@ -301,6 +333,11 @@ int get_device_by_uuid(uuid_d dev_uuid, const char* label, char* partition,
 {
   return -EOPNOTSUPP;
 }
+
+void get_dm_parents(const string& dev, set<string> *ls)
+{
+}
+
 #elif defined(__FreeBSD__)
 #include <sys/disk.h>
 
@@ -336,6 +373,11 @@ int get_device_by_fd(int fd, char *partition, char *device, size_t max)
 {
   return -EOPNOTSUPP;
 }
+
+void get_dm_parents(const string& dev, set<string> *ls)
+{
+}
+
 #else
 int get_block_device_size(int fd, int64_t *psize)
 {
@@ -367,4 +409,7 @@ int get_device_by_fd(int fd, char *partition, char *device, size_t max)
 {
   return -EOPNOTSUPP;
 }
+void get_dm_parents(const string& dev, set<string> *ls)
+{
+}
 #endif
index eef3a25cab89b74e1f1e11633611067ed62bb671..c480c2e02b01d4ab86fd51f735f7472ffd56171a 100644 (file)
@@ -1,6 +1,9 @@
 #ifndef __CEPH_COMMON_BLKDEV_H
 #define __CEPH_COMMON_BLKDEV_H
 
+#include <set>
+#include <string>
+
 /* for testing purposes */
 extern void set_block_device_sandbox_dir(const char *dir);
 
@@ -26,4 +29,6 @@ extern bool block_device_support_discard(const char *devname);
 extern bool block_device_is_rotational(const char *devname);
 extern int block_device_model(const char *devname, char *model, size_t max);
 
+extern void get_dm_parents(const std::string& dev, std::set<std::string> *ls);
+
 #endif
index 83fb094070ae7a118e8e7a382cb34eef24eb7572..61b7aee9b43e259bb7a4903da2fffd5fb7d36e8b 100644 (file)
@@ -128,6 +128,17 @@ public:
 
   virtual int collect_metadata(const std::string& prefix, std::map<std::string,std::string> *pm) const = 0;
 
+  virtual int get_devname(string *out) {
+    return -ENOENT;
+  }
+  virtual int get_devices(set<string> *ls) {
+    string s;
+    if (get_devname(&s) == 0) {
+      ls->insert(s);
+    }
+    return 0;
+  }
+
   virtual int read(
     uint64_t off,
     uint64_t len,
index 828ce5f9dacc6e76becdc5693919cc53736cccc0..cfa626d493e8c11a10ee50f655416870abc0e587 100644 (file)
@@ -137,6 +137,7 @@ int KernelDevice::open(const string& p)
     } else {
       dout(20) << __func__ << " devname " << devname << dendl;
       rotational = block_device_is_rotational(devname);
+      this->devname = devname;
     }
   }
 
@@ -170,6 +171,18 @@ int KernelDevice::open(const string& p)
   return r;
 }
 
+int KernelDevice::get_devices(std::set<std::string> *ls)
+{
+  if (devname.empty()) {
+    return 0;
+  }
+  ls->insert(devname);
+  if (devname.find("dm-") == 0) {
+    get_dm_parents(devname, ls);
+  }
+  return 0;
+}
+
 void KernelDevice::close()
 {
   dout(1) << __func__ << dendl;
index e5a21a10a2e34580f008cd0e9f75f6964c20fe5b..c0c797f0461834b12c32540551eaefc4e7f4e247 100644 (file)
@@ -29,6 +29,8 @@ class KernelDevice : public BlockDevice {
   FS *fs;
   bool aio, dio;
 
+  std::string devname;  ///< kernel dev name (/sys/block/$devname), if any
+
   Mutex debug_lock;
   interval_set<uint64_t> debug_inflight;
 
@@ -76,6 +78,14 @@ public:
   void aio_submit(IOContext *ioc) override;
 
   int collect_metadata(const std::string& prefix, map<std::string,std::string> *pm) const override;
+  int get_devname(std::string *s) override {
+    if (devname.empty()) {
+      return -ENOENT;
+    }
+    *s = devname;
+    return 0;
+  }
+  int get_devices(std::set<std::string> *ls) override;
 
   int read(uint64_t off, uint64_t len, bufferlist *pbl,
           IOContext *ioc,