From 805fcee0ae92922b0679270c3779949fc2d489f8 Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Fri, 20 Oct 2017 17:11:39 -0500 Subject: [PATCH] os/bluestore/BlockDevice: add get_devname(), get_devices() 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 --- src/common/blkdev.cc | 45 ++++++++++++++++++++++++++++++++ src/common/blkdev.h | 5 ++++ src/os/bluestore/BlockDevice.h | 11 ++++++++ src/os/bluestore/KernelDevice.cc | 13 +++++++++ src/os/bluestore/KernelDevice.h | 10 +++++++ 5 files changed, 84 insertions(+) diff --git a/src/common/blkdev.cc b/src/common/blkdev.cc index d95a397a844..c71a05bd2b4 100644 --- a/src/common/blkdev.cc +++ b/src/common/blkdev.cc @@ -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 *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 *ls) +{ + std::string p = std::string("/sys/block/") + dev + "/slaves"; + std::set 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 @@ -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 *ls) +{ +} + #elif defined(__FreeBSD__) #include @@ -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 *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 *ls) +{ +} #endif diff --git a/src/common/blkdev.h b/src/common/blkdev.h index eef3a25cab8..c480c2e02b0 100644 --- a/src/common/blkdev.h +++ b/src/common/blkdev.h @@ -1,6 +1,9 @@ #ifndef __CEPH_COMMON_BLKDEV_H #define __CEPH_COMMON_BLKDEV_H +#include +#include + /* 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 *ls); + #endif diff --git a/src/os/bluestore/BlockDevice.h b/src/os/bluestore/BlockDevice.h index 83fb094070a..61b7aee9b43 100644 --- a/src/os/bluestore/BlockDevice.h +++ b/src/os/bluestore/BlockDevice.h @@ -128,6 +128,17 @@ public: virtual int collect_metadata(const std::string& prefix, std::map *pm) const = 0; + virtual int get_devname(string *out) { + return -ENOENT; + } + virtual int get_devices(set *ls) { + string s; + if (get_devname(&s) == 0) { + ls->insert(s); + } + return 0; + } + virtual int read( uint64_t off, uint64_t len, diff --git a/src/os/bluestore/KernelDevice.cc b/src/os/bluestore/KernelDevice.cc index 828ce5f9dac..cfa626d493e 100644 --- a/src/os/bluestore/KernelDevice.cc +++ b/src/os/bluestore/KernelDevice.cc @@ -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 *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; diff --git a/src/os/bluestore/KernelDevice.h b/src/os/bluestore/KernelDevice.h index e5a21a10a2e..c0c797f0461 100644 --- a/src/os/bluestore/KernelDevice.h +++ b/src/os/bluestore/KernelDevice.h @@ -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 debug_inflight; @@ -76,6 +78,14 @@ public: void aio_submit(IOContext *ioc) override; int collect_metadata(const std::string& prefix, map *pm) const override; + int get_devname(std::string *s) override { + if (devname.empty()) { + return -ENOENT; + } + *s = devname; + return 0; + } + int get_devices(std::set *ls) override; int read(uint64_t off, uint64_t len, bufferlist *pbl, IOContext *ioc, -- 2.39.5