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>
{
return -EOPNOTSUPP;
}
+
+void get_dm_parents(const string& dev, set<string> *ls)
+{
+}
+
#elif defined(__FreeBSD__)
#include <sys/disk.h>
{
return -EOPNOTSUPP;
}
+
+void get_dm_parents(const string& dev, set<string> *ls)
+{
+}
+
#else
int get_block_device_size(int fd, int64_t *psize)
{
{
return -EOPNOTSUPP;
}
+void get_dm_parents(const string& dev, set<string> *ls)
+{
+}
#endif
#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);
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
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,
} else {
dout(20) << __func__ << " devname " << devname << dendl;
rotational = block_device_is_rotational(devname);
+ this->devname = devname;
}
}
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;
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;
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,